blob: ceb6a20c484f09104b9feba313cede6e4ccbbe3e [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"
vincentc1a03d42005-09-28 15:47:44 +000035#include "md5.h"
paul718e3742002-12-13 20:15:29 +000036
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;
vincentc1a03d42005-09-28 15:47:44 +0000263 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000264 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. */
vincentc1a03d42005-09-28 15:47:44 +0000300 memset(&ctx, 0, sizeof(ctx));
301 MD5Init(&ctx);
302 MD5Update(&ctx, ibuf, length);
303 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
304 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000305
306 /* compare the two */
307 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
308 {
309 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
310 IF_NAME (oi));
311 return 0;
312 }
313
314 /* save neighbor's crypt_seqnum */
315 if (nbr)
316 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
317 return 1;
318}
319
320/* This function is called from ospf_write(), it will detect the
321 authentication scheme and if it is MD5, it will change the sequence
322 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000323static int
paul718e3742002-12-13 20:15:29 +0000324ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
325{
326 struct ospf_header *ospfh;
327 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000328 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000329 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000330 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000331 struct crypt_key *ck;
paul4dadc292005-05-06 21:37:42 +0000332 const char *auth_key;
paul718e3742002-12-13 20:15:29 +0000333
334 ibuf = STREAM_DATA (op->s);
335 ospfh = (struct ospf_header *) ibuf;
336
337 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
338 return 0;
339
340 /* We do this here so when we dup a packet, we don't have to
341 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000342 t = (time(NULL) & 0xFFFFFFFF);
343 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
344 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000345
346 /* Get MD5 Authentication key from auth_key list. */
347 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul4dadc292005-05-06 21:37:42 +0000348 auth_key = "";
paul718e3742002-12-13 20:15:29 +0000349 else
350 {
paul1eb8ef22005-04-07 07:30:20 +0000351 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000352 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000353 }
354
355 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000356 memset(&ctx, 0, sizeof(ctx));
357 MD5Init(&ctx);
358 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
359 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
360 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000361
362 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000363 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000364
365 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000366 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
367
paul37163d62003-02-03 18:40:56 +0000368 if (stream_get_endp(op->s) != op->length)
369 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 +0000370
371 return OSPF_AUTH_MD5_SIZE;
372}
373
374
paul4dadc292005-05-06 21:37:42 +0000375static int
paul718e3742002-12-13 20:15:29 +0000376ospf_ls_req_timer (struct thread *thread)
377{
378 struct ospf_neighbor *nbr;
379
380 nbr = THREAD_ARG (thread);
381 nbr->t_ls_req = NULL;
382
383 /* Send Link State Request. */
384 if (ospf_ls_request_count (nbr))
385 ospf_ls_req_send (nbr);
386
387 /* Set Link State Request retransmission timer. */
388 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
389
390 return 0;
391}
392
393void
394ospf_ls_req_event (struct ospf_neighbor *nbr)
395{
396 if (nbr->t_ls_req)
397 {
398 thread_cancel (nbr->t_ls_req);
399 nbr->t_ls_req = NULL;
400 }
401 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
402}
403
404/* Cyclic timer function. Fist registered in ospf_nbr_new () in
405 ospf_neighbor.c */
406int
407ospf_ls_upd_timer (struct thread *thread)
408{
409 struct ospf_neighbor *nbr;
410
411 nbr = THREAD_ARG (thread);
412 nbr->t_ls_upd = NULL;
413
414 /* Send Link State Update. */
415 if (ospf_ls_retransmit_count (nbr) > 0)
416 {
hasso52dc7ee2004-09-23 19:18:23 +0000417 struct list *update;
paul718e3742002-12-13 20:15:29 +0000418 struct ospf_lsdb *lsdb;
419 int i;
420 struct timeval now;
421 int retransmit_interval;
422
423 gettimeofday (&now, NULL);
424 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
425
426 lsdb = &nbr->ls_rxmt;
427 update = list_new ();
428
429 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
430 {
431 struct route_table *table = lsdb->type[i].db;
432 struct route_node *rn;
433
434 for (rn = route_top (table); rn; rn = route_next (rn))
435 {
436 struct ospf_lsa *lsa;
437
438 if ((lsa = rn->info) != NULL)
439 /* Don't retransmit an LSA if we received it within
440 the last RxmtInterval seconds - this is to allow the
441 neighbour a chance to acknowledge the LSA as it may
442 have ben just received before the retransmit timer
443 fired. This is a small tweak to what is in the RFC,
444 but it will cut out out a lot of retransmit traffic
445 - MAG */
446 if (tv_cmp (tv_sub (now, lsa->tv_recv),
447 int2tv (retransmit_interval)) >= 0)
448 listnode_add (update, rn->info);
449 }
450 }
451
452 if (listcount (update) > 0)
453 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
454 list_delete (update);
455 }
456
457 /* Set LS Update retransmission timer. */
458 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
459
460 return 0;
461}
462
463int
464ospf_ls_ack_timer (struct thread *thread)
465{
466 struct ospf_interface *oi;
467
468 oi = THREAD_ARG (thread);
469 oi->t_ls_ack = NULL;
470
471 /* Send Link State Acknowledgment. */
472 if (listcount (oi->ls_ack) > 0)
473 ospf_ls_ack_send_delayed (oi);
474
475 /* Set LS Ack timer. */
476 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
477
478 return 0;
479}
480
paul0bfeca32004-09-24 08:07:54 +0000481#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000482static void
paul6a99f832004-09-27 12:56:30 +0000483ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000484 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000485 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000486{
487#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000488 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000489 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000490 int ret;
paul0bfeca32004-09-24 08:07:54 +0000491
492 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000493 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000494
495 /* we can but try.
496 *
497 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
498 * well as the IP_MF flag, making this all quite pointless.
499 *
500 * However, for a system on which IP_MF is left alone, and ip_id left
501 * alone or else which sets same ip_id for each fragment this might
502 * work, eg linux.
503 *
504 * XXX-TODO: It would be much nicer to have the kernel's use their
505 * existing fragmentation support to do this for us. Bugs/RFEs need to
506 * be raised against the various kernels.
507 */
508
509 /* set More Frag */
510 iph->ip_off |= IP_MF;
511
512 /* ip frag offset is expressed in units of 8byte words */
513 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
514
paul62d8e962004-11-02 20:26:45 +0000515 iovp = &msg->msg_iov[1];
516
paul0bfeca32004-09-24 08:07:54 +0000517 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
518 > maxdatasize )
519 {
520 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000521 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
522 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000523 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000524
paul18b12c32004-10-05 14:38:29 +0000525 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000526
paul6a99f832004-09-27 12:56:30 +0000527 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000528
paul18b12c32004-10-05 14:38:29 +0000529 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000530
531 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000532 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000533 " id %d, off %d, len %d, mtu %u failed with %s",
534 inet_ntoa (iph->ip_dst),
535 iph->ip_id,
536 iph->ip_off,
537 iph->ip_len,
538 mtu,
539 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000540
paul37ccfa32004-10-31 11:24:51 +0000541 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
542 {
ajs2a42e282004-12-08 18:43:03 +0000543 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000544 iph->ip_id, iph->ip_off, iph->ip_len,
545 inet_ntoa (iph->ip_dst));
546 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
547 {
ajs2a42e282004-12-08 18:43:03 +0000548 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000549 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000550 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000551 }
552 }
553
paul0bfeca32004-09-24 08:07:54 +0000554 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000555 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000556 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000557 }
558
559 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000560 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
561 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000562 iph->ip_off &= (~IP_MF);
563}
564#endif /* WANT_OSPF_WRITE_FRAGMENT */
565
ajs5dcbdf82005-03-29 16:13:49 +0000566static int
paul718e3742002-12-13 20:15:29 +0000567ospf_write (struct thread *thread)
568{
paul68980082003-03-25 05:07:42 +0000569 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000570 struct ospf_interface *oi;
571 struct ospf_packet *op;
572 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000573 struct ip iph;
574 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000575 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000576 u_char type;
577 int ret;
578 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000579 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000580#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000581 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000582#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000583 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000584#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000585
paul68980082003-03-25 05:07:42 +0000586 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000587
paul68980082003-03-25 05:07:42 +0000588 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000589 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000590 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000591 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000592
593#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000594 /* seed ipid static with low order bits of time */
595 if (ipid == 0)
596 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000597#endif /* WANT_OSPF_WRITE_FRAGMENT */
598
paul68b73392004-09-12 14:21:37 +0000599 /* convenience - max OSPF data per packet */
600 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
601
paul718e3742002-12-13 20:15:29 +0000602 /* Get one packet from queue. */
603 op = ospf_fifo_head (oi->obuf);
604 assert (op);
605 assert (op->length >= OSPF_HEADER_SIZE);
606
paul68980082003-03-25 05:07:42 +0000607 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
608 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000609 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
610
paul718e3742002-12-13 20:15:29 +0000611 /* Rewrite the md5 signature & update the seq */
612 ospf_make_md5_digest (oi, op);
613
paul37ccfa32004-10-31 11:24:51 +0000614 /* Retrieve OSPF packet type. */
615 stream_set_getp (op->s, 1);
616 type = stream_getc (op->s);
617
paul68b73392004-09-12 14:21:37 +0000618 /* reset get pointer */
619 stream_set_getp (op->s, 0);
620
621 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000622 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000623
paul718e3742002-12-13 20:15:29 +0000624 sa_dst.sin_family = AF_INET;
625#ifdef HAVE_SIN_LEN
626 sa_dst.sin_len = sizeof(sa_dst);
627#endif /* HAVE_SIN_LEN */
628 sa_dst.sin_addr = op->dst;
629 sa_dst.sin_port = htons (0);
630
631 /* Set DONTROUTE flag if dst is unicast. */
632 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
633 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
634 flags = MSG_DONTROUTE;
635
paul68b73392004-09-12 14:21:37 +0000636 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
637 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000638 if ( sizeof (struct ip)
639 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000640 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
641
paul718e3742002-12-13 20:15:29 +0000642 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000643 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000644 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000645
paul0bfeca32004-09-24 08:07:54 +0000646#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000647 /* XXX-MT: not thread-safe at all..
648 * XXX: this presumes this is only programme sending OSPF packets
649 * otherwise, no guarantee ipid will be unique
650 */
651 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000652#endif /* WANT_OSPF_WRITE_FRAGMENT */
653
paul718e3742002-12-13 20:15:29 +0000654 iph.ip_off = 0;
655 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
656 iph.ip_ttl = OSPF_VL_IP_TTL;
657 else
658 iph.ip_ttl = OSPF_IP_TTL;
659 iph.ip_p = IPPROTO_OSPFIGP;
660 iph.ip_sum = 0;
661 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
662 iph.ip_dst.s_addr = op->dst.s_addr;
663
664 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000665 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000666 msg.msg_namelen = sizeof (sa_dst);
667 msg.msg_iov = iov;
668 msg.msg_iovlen = 2;
669 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000670 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
671 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000672 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000673
674 /* Sadly we can not rely on kernels to fragment packets because of either
675 * IP_HDRINCL and/or multicast destination being set.
676 */
paul0bfeca32004-09-24 08:07:54 +0000677#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000678 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000679 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
680 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000681#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000682
683 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000684 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000685 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000686 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000687
688 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000689 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000690 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000691 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000692 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000693
paul718e3742002-12-13 20:15:29 +0000694 /* Show debug sending packet. */
695 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
696 {
697 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
698 {
ajs2a42e282004-12-08 18:43:03 +0000699 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000700 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000701 stream_set_getp (op->s, 0);
702 ospf_packet_dump (op->s);
703 }
704
ajs2a42e282004-12-08 18:43:03 +0000705 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000706 ospf_packet_type_str[type], inet_ntoa (op->dst),
707 IF_NAME (oi));
708
709 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000710 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000711 }
712
713 /* Now delete packet from queue. */
714 ospf_packet_delete (oi);
715
716 if (ospf_fifo_head (oi->obuf) == NULL)
717 {
718 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000719 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000720 }
721
722 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000723 if (!list_isempty (ospf->oi_write_q))
724 ospf->t_write =
725 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000726
727 return 0;
728}
729
730/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000731static void
paul718e3742002-12-13 20:15:29 +0000732ospf_hello (struct ip *iph, struct ospf_header *ospfh,
733 struct stream * s, struct ospf_interface *oi, int size)
734{
735 struct ospf_hello *hello;
736 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000737 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000738 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000739
740 /* increment statistics. */
741 oi->hello_in++;
742
743 hello = (struct ospf_hello *) STREAM_PNT (s);
744
745 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000746 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000747 {
748 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
749 {
ajs2a42e282004-12-08 18:43:03 +0000750 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000751 "dropping.",
752 ospf_packet_type_str[ospfh->type],
753 inet_ntoa (iph->ip_src));
754 }
755 return;
756 }
paul718e3742002-12-13 20:15:29 +0000757
758 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000759 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000760 char buf[3][INET_ADDRSTRLEN];
761 zlog_warn("Warning: ignoring HELLO from router %s sent to %s; we "
762 "should not receive hellos on passive interface %s!",
763 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
764 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
765 inet_ntop(AF_INET, &oi->address->u.prefix4,
766 buf[2], sizeof(buf[2])));
767 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
768 {
769 /* Try to fix multicast membership. */
770 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
771 ospf_if_set_multicast(oi);
772 }
paul718e3742002-12-13 20:15:29 +0000773 return;
paulf2c80652002-12-13 21:44:27 +0000774 }
paul718e3742002-12-13 20:15:29 +0000775
776 /* get neighbor prefix. */
777 p.family = AF_INET;
778 p.prefixlen = ip_masklen (hello->network_mask);
779 p.u.prefix4 = iph->ip_src;
780
781 /* Compare network mask. */
782 /* Checking is ignored for Point-to-Point and Virtual link. */
783 if (oi->type != OSPF_IFTYPE_POINTOPOINT
784 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
785 if (oi->address->prefixlen != p.prefixlen)
786 {
787 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
788 inet_ntoa (ospfh->router_id));
789 return;
790 }
791
792 /* Compare Hello Interval. */
793 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
794 {
795 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
796 inet_ntoa (ospfh->router_id));
797 return;
798 }
799
800 /* Compare Router Dead Interval. */
801 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
802 {
803 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
804 inet_ntoa (ospfh->router_id));
805 return;
806 }
807
808 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000809 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000810 inet_ntoa (ospfh->router_id),
811 ospf_options_dump (hello->options));
812
813 /* Compare options. */
814#define REJECT_IF_TBIT_ON 1 /* XXX */
815#ifdef REJECT_IF_TBIT_ON
816 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
817 {
818 /*
819 * This router does not support non-zero TOS.
820 * Drop this Hello packet not to establish neighbor relationship.
821 */
822 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
823 inet_ntoa (ospfh->router_id));
824 return;
825 }
826#endif /* REJECT_IF_TBIT_ON */
827
828#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000829 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000830 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
831 {
832 /*
833 * This router does know the correct usage of O-bit
834 * the bit should be set in DD packet only.
835 */
836 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
837 inet_ntoa (ospfh->router_id));
838#ifdef STRICT_OBIT_USAGE_CHECK
839 return; /* Reject this packet. */
840#else /* STRICT_OBIT_USAGE_CHECK */
841 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
842#endif /* STRICT_OBIT_USAGE_CHECK */
843 }
844#endif /* HAVE_OPAQUE_LSA */
845
846 /* new for NSSA is to ensure that NP is on and E is off */
847
paul718e3742002-12-13 20:15:29 +0000848 if (oi->area->external_routing == OSPF_AREA_NSSA)
849 {
850 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
851 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
852 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
853 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
854 {
855 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
856 return;
857 }
858 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000859 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000860 }
861 else
paul718e3742002-12-13 20:15:29 +0000862 /* The setting of the E-bit found in the Hello Packet's Options
863 field must match this area's ExternalRoutingCapability A
864 mismatch causes processing to stop and the packet to be
865 dropped. The setting of the rest of the bits in the Hello
866 Packet's Options field should be ignored. */
867 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
868 CHECK_FLAG (hello->options, OSPF_OPTION_E))
869 {
ajs3aa8d5f2004-12-11 18:00:06 +0000870 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
871 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000872 return;
873 }
paul718e3742002-12-13 20:15:29 +0000874
pauld3f0d622004-05-05 15:27:15 +0000875 /* get neighbour struct */
876 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
877
878 /* neighbour must be valid, ospf_nbr_get creates if none existed */
879 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000880
881 old_state = nbr->state;
882
883 /* Add event to thread. */
884 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
885
886 /* RFC2328 Section 9.5.1
887 If the router is not eligible to become Designated Router,
888 (snip) It must also send an Hello Packet in reply to an
889 Hello Packet received from any eligible neighbor (other than
890 the current Designated Router and Backup Designated Router). */
891 if (oi->type == OSPF_IFTYPE_NBMA)
892 if (PRIORITY(oi) == 0 && hello->priority > 0
893 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
894 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
895 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
896 OSPF_HELLO_REPLY_DELAY);
897
898 /* on NBMA network type, it happens to receive bidirectional Hello packet
899 without advance 1-Way Received event.
900 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
901 if (oi->type == OSPF_IFTYPE_NBMA &&
902 (old_state == NSM_Down || old_state == NSM_Attempt))
903 {
904 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
905 nbr->priority = hello->priority;
906 nbr->d_router = hello->d_router;
907 nbr->bd_router = hello->bd_router;
908 return;
909 }
910
paul68980082003-03-25 05:07:42 +0000911 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000912 size - OSPF_HELLO_MIN_SIZE))
913 {
914 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
915 nbr->options |= hello->options;
916 }
917 else
918 {
919 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
920 /* Set neighbor information. */
921 nbr->priority = hello->priority;
922 nbr->d_router = hello->d_router;
923 nbr->bd_router = hello->bd_router;
924 return;
925 }
926
927 /* If neighbor itself declares DR and no BDR exists,
928 cause event BackupSeen */
929 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
930 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
931 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
932
933 /* neighbor itself declares BDR. */
934 if (oi->state == ISM_Waiting &&
935 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
936 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
937
938 /* had not previously. */
939 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
940 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
941 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
942 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
943 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
944
945 /* had not previously. */
946 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
947 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
948 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
949 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
950 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
951
952 /* Neighbor priority check. */
953 if (nbr->priority >= 0 && nbr->priority != hello->priority)
954 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
955
956 /* Set neighbor information. */
957 nbr->priority = hello->priority;
958 nbr->d_router = hello->d_router;
959 nbr->bd_router = hello->bd_router;
960}
961
962/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000963static void
paul718e3742002-12-13 20:15:29 +0000964ospf_db_desc_save_current (struct ospf_neighbor *nbr,
965 struct ospf_db_desc *dd)
966{
967 nbr->last_recv.flags = dd->flags;
968 nbr->last_recv.options = dd->options;
969 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
970}
971
972/* Process rest of DD packet. */
973static void
974ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
975 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
976 u_int16_t size)
977{
978 struct ospf_lsa *new, *find;
979 struct lsa_header *lsah;
980
paul9985f832005-02-09 15:51:56 +0000981 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000982 for (size -= OSPF_DB_DESC_MIN_SIZE;
983 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
984 {
985 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000986 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000987
988 /* Unknown LS type. */
989 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
990 {
ajsbec595a2004-11-30 22:38:43 +0000991 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000992 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
993 return;
994 }
995
996#ifdef HAVE_OPAQUE_LSA
997 if (IS_OPAQUE_LSA (lsah->type)
998 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
999 {
1000 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1001 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1002 return;
1003 }
1004#endif /* HAVE_OPAQUE_LSA */
1005
1006 switch (lsah->type)
1007 {
1008 case OSPF_AS_EXTERNAL_LSA:
1009#ifdef HAVE_OPAQUE_LSA
1010 case OSPF_OPAQUE_AS_LSA:
1011#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001012 /* Check for stub area. Reject if AS-External from stub but
1013 allow if from NSSA. */
1014 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001015 {
1016 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1017 lsah->type, inet_ntoa (lsah->id),
1018 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1019 "STUB" : "NSSA");
1020 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1021 return;
1022 }
1023 break;
1024 default:
1025 break;
1026 }
1027
1028 /* Create LS-request object. */
1029 new = ospf_ls_request_new (lsah);
1030
1031 /* Lookup received LSA, then add LS request list. */
1032 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1033 if (!find || ospf_lsa_more_recent (find, new) < 0)
1034 {
1035 ospf_ls_request_add (nbr, new);
1036 ospf_lsa_discard (new);
1037 }
1038 else
1039 {
1040 /* Received LSA is not recent. */
1041 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001042 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001043 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1044 ospf_lsa_discard (new);
1045 continue;
1046 }
1047 }
1048
1049 /* Master */
1050 if (IS_SET_DD_MS (nbr->dd_flags))
1051 {
1052 nbr->dd_seqnum++;
1053 /* Entire DD packet sent. */
1054 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1055 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1056 else
1057 /* Send new DD packet. */
1058 ospf_db_desc_send (nbr);
1059 }
1060 /* Slave */
1061 else
1062 {
1063 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1064
1065 /* When master's more flags is not set. */
1066 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1067 {
1068 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1069 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1070 }
1071
ajsbec595a2004-11-30 22:38:43 +00001072 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001073 ospf_db_desc_send (nbr);
1074 }
1075
1076 /* Save received neighbor values from DD. */
1077 ospf_db_desc_save_current (nbr, dd);
1078}
1079
paul4dadc292005-05-06 21:37:42 +00001080static int
paul718e3742002-12-13 20:15:29 +00001081ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1082{
1083 /* Is DD duplicated? */
1084 if (dd->options == nbr->last_recv.options &&
1085 dd->flags == nbr->last_recv.flags &&
1086 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1087 return 1;
1088
1089 return 0;
1090}
1091
1092/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001093static void
paul718e3742002-12-13 20:15:29 +00001094ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1095 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1096{
1097 struct ospf_db_desc *dd;
1098 struct ospf_neighbor *nbr;
1099
1100 /* Increment statistics. */
1101 oi->db_desc_in++;
1102
1103 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001104
pauld3f0d622004-05-05 15:27:15 +00001105 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001106 if (nbr == NULL)
1107 {
1108 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1109 inet_ntoa (ospfh->router_id));
1110 return;
1111 }
1112
1113 /* Check MTU. */
1114 if (ntohs (dd->mtu) > oi->ifp->mtu)
1115 {
ajs3aa8d5f2004-12-11 18:00:06 +00001116 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1117 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1118 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001119 return;
1120 }
1121
pauld363df22003-06-19 00:26:34 +00001122 /*
1123 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1124 * required. In fact at least JunOS sends DD packets with P bit clear.
1125 * Until proper solution is developped, this hack should help.
1126 *
1127 * Update: According to the RFCs, N bit is specified /only/ for Hello
1128 * options, unfortunately its use in DD options is not specified. Hence some
1129 * implementations follow E-bit semantics and set it in DD options, and some
1130 * treat it as unspecified and hence follow the directive "default for
1131 * options is clear", ie unset.
1132 *
1133 * Reset the flag, as ospfd follows E-bit semantics.
1134 */
1135 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1136 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1137 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1138 {
1139 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001140 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001141 inet_ntoa (nbr->router_id) );
1142 SET_FLAG (dd->options, OSPF_OPTION_NP);
1143 }
pauld363df22003-06-19 00:26:34 +00001144
paul718e3742002-12-13 20:15:29 +00001145#ifdef REJECT_IF_TBIT_ON
1146 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1147 {
1148 /*
1149 * In Hello protocol, optional capability must have checked
1150 * to prevent this T-bit enabled router be my neighbor.
1151 */
1152 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1153 return;
1154 }
1155#endif /* REJECT_IF_TBIT_ON */
1156
1157#ifdef HAVE_OPAQUE_LSA
1158 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001159 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001160 {
1161 /*
1162 * This node is not configured to handle O-bit, for now.
1163 * Clear it to ignore unsupported capability proposed by neighbor.
1164 */
1165 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1166 }
1167#endif /* HAVE_OPAQUE_LSA */
1168
1169 /* Process DD packet by neighbor status. */
1170 switch (nbr->state)
1171 {
1172 case NSM_Down:
1173 case NSM_Attempt:
1174 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001175 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001176 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001177 LOOKUP (ospf_nsm_state_msg, nbr->state));
1178 break;
1179 case NSM_Init:
1180 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1181 /* If the new state is ExStart, the processing of the current
1182 packet should then continue in this new state by falling
1183 through to case ExStart below. */
1184 if (nbr->state != NSM_ExStart)
1185 break;
1186 case NSM_ExStart:
1187 /* Initial DBD */
1188 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1189 (size == OSPF_DB_DESC_MIN_SIZE))
1190 {
paul68980082003-03-25 05:07:42 +00001191 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001192 {
1193 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001194 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001195 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001196 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1197 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1198 }
1199 else
1200 {
1201 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001202 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1203 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001204 break;
1205 }
1206 }
1207 /* Ack from the Slave */
1208 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1209 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001210 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001211 {
ajs17eaa722004-12-29 21:04:48 +00001212 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001213 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001214 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1215 }
1216 else
1217 {
ajs3aa8d5f2004-12-11 18:00:06 +00001218 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1219 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001220 break;
1221 }
1222
1223 /* This is where the real Options are saved */
1224 nbr->options = dd->options;
1225
1226#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001227 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001228 {
1229 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001230 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001231 inet_ntoa (nbr->router_id),
1232 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1233
1234 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1235 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1236 {
1237 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1238 /* This situation is undesirable, but not a real error. */
1239 }
1240 }
1241#endif /* HAVE_OPAQUE_LSA */
1242
1243 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1244
1245 /* continue processing rest of packet. */
1246 ospf_db_desc_proc (s, oi, nbr, dd, size);
1247 break;
1248 case NSM_Exchange:
1249 if (ospf_db_desc_is_dup (dd, nbr))
1250 {
1251 if (IS_SET_DD_MS (nbr->dd_flags))
1252 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001253 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1254 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001255 else
1256 /* Slave: cause to retransmit the last Database Description. */
1257 {
ajs3aa8d5f2004-12-11 18:00:06 +00001258 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1259 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001260 ospf_db_desc_resend (nbr);
1261 }
1262 break;
1263 }
1264
1265 /* Otherwise DD packet should be checked. */
1266 /* Check Master/Slave bit mismatch */
1267 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1268 {
ajs3aa8d5f2004-12-11 18:00:06 +00001269 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1270 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001271 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1272 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001273 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001274 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001275 break;
1276 }
1277
1278 /* Check initialize bit is set. */
1279 if (IS_SET_DD_I (dd->flags))
1280 {
ajs3aa8d5f2004-12-11 18:00:06 +00001281 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1282 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001283 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1284 break;
1285 }
1286
1287 /* Check DD Options. */
1288 if (dd->options != nbr->options)
1289 {
1290#ifdef ORIGINAL_CODING
1291 /* Save the new options for debugging */
1292 nbr->options = dd->options;
1293#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001294 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1295 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001296 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1297 break;
1298 }
1299
1300 /* Check DD sequence number. */
1301 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1302 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1303 (!IS_SET_DD_MS (nbr->dd_flags) &&
1304 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1305 {
ajs3aa8d5f2004-12-11 18:00:06 +00001306 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1307 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001308 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1309 break;
1310 }
1311
1312 /* Continue processing rest of packet. */
1313 ospf_db_desc_proc (s, oi, nbr, dd, size);
1314 break;
1315 case NSM_Loading:
1316 case NSM_Full:
1317 if (ospf_db_desc_is_dup (dd, nbr))
1318 {
1319 if (IS_SET_DD_MS (nbr->dd_flags))
1320 {
1321 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001322 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1323 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001324 break;
1325 }
1326 else
1327 {
1328 struct timeval t, now;
1329 gettimeofday (&now, NULL);
1330 t = tv_sub (now, nbr->last_send_ts);
1331 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1332 {
1333 /* In states Loading and Full the slave must resend
1334 its last Database Description packet in response to
1335 duplicate Database Description packets received
1336 from the master. For this reason the slave must
1337 wait RouterDeadInterval seconds before freeing the
1338 last Database Description packet. Reception of a
1339 Database Description packet from the master after
1340 this interval will generate a SeqNumberMismatch
1341 neighbor event. RFC2328 Section 10.8 */
1342 ospf_db_desc_resend (nbr);
1343 break;
1344 }
1345 }
1346 }
1347
1348 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1349 break;
1350 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001351 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1352 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001353 break;
1354 }
1355}
1356
1357#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1358
1359/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001360static void
paul718e3742002-12-13 20:15:29 +00001361ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1362 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1363{
1364 struct ospf_neighbor *nbr;
1365 u_int32_t ls_type;
1366 struct in_addr ls_id;
1367 struct in_addr adv_router;
1368 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001369 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001370 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001371
1372 /* Increment statistics. */
1373 oi->ls_req_in++;
1374
pauld3f0d622004-05-05 15:27:15 +00001375 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001376 if (nbr == NULL)
1377 {
1378 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1379 inet_ntoa (ospfh->router_id));
1380 return;
1381 }
1382
1383 /* Neighbor State should be Exchange or later. */
1384 if (nbr->state != NSM_Exchange &&
1385 nbr->state != NSM_Loading &&
1386 nbr->state != NSM_Full)
1387 {
ajsbec595a2004-11-30 22:38:43 +00001388 zlog_warn ("Link State Request received from %s: "
1389 "Neighbor state is %s, packet discarded.",
1390 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001391 LOOKUP (ospf_nsm_state_msg, nbr->state));
1392 return;
1393 }
1394
1395 /* Send Link State Update for ALL requested LSAs. */
1396 ls_upd = list_new ();
1397 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1398
1399 while (size >= OSPF_LSA_KEY_SIZE)
1400 {
1401 /* Get one slice of Link State Request. */
1402 ls_type = stream_getl (s);
1403 ls_id.s_addr = stream_get_ipv4 (s);
1404 adv_router.s_addr = stream_get_ipv4 (s);
1405
1406 /* Verify LSA type. */
1407 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1408 {
1409 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1410 list_delete (ls_upd);
1411 return;
1412 }
1413
1414 /* Search proper LSA in LSDB. */
1415 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1416 if (find == NULL)
1417 {
1418 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1419 list_delete (ls_upd);
1420 return;
1421 }
1422
gdt86f1fd92005-01-10 14:20:43 +00001423 /* Packet overflows MTU size, send immediately. */
1424 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001425 {
1426 if (oi->type == OSPF_IFTYPE_NBMA)
1427 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1428 else
1429 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1430
1431 /* Only remove list contents. Keep ls_upd. */
1432 list_delete_all_node (ls_upd);
1433
1434 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1435 }
1436
1437 /* Append LSA to update list. */
1438 listnode_add (ls_upd, find);
1439 length += ntohs (find->data->length);
1440
1441 size -= OSPF_LSA_KEY_SIZE;
1442 }
1443
1444 /* Send rest of Link State Update. */
1445 if (listcount (ls_upd) > 0)
1446 {
1447 if (oi->type == OSPF_IFTYPE_NBMA)
1448 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1449 else
1450 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1451
1452 list_delete (ls_upd);
1453 }
1454 else
1455 list_free (ls_upd);
1456}
1457
1458/* Get the list of LSAs from Link State Update packet.
1459 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001460static struct list *
paul718e3742002-12-13 20:15:29 +00001461ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1462 struct ospf_interface *oi, size_t size)
1463{
1464 u_int16_t count, sum;
1465 u_int32_t length;
1466 struct lsa_header *lsah;
1467 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001468 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001469
1470 lsas = list_new ();
1471
1472 count = stream_getl (s);
1473 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1474
1475 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001476 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001477 {
1478 lsah = (struct lsa_header *) STREAM_PNT (s);
1479 length = ntohs (lsah->length);
1480
1481 if (length > size)
1482 {
1483 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1484 break;
1485 }
1486
1487 /* Validate the LSA's LS checksum. */
1488 sum = lsah->checksum;
1489 if (sum != ospf_lsa_checksum (lsah))
1490 {
1491 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1492 sum, lsah->checksum);
1493 continue;
1494 }
1495
1496 /* Examine the LSA's LS type. */
1497 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1498 {
1499 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1500 continue;
1501 }
1502
1503 /*
1504 * What if the received LSA's age is greater than MaxAge?
1505 * Treat it as a MaxAge case -- endo.
1506 */
1507 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1508 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1509
1510#ifdef HAVE_OPAQUE_LSA
1511 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1512 {
1513#ifdef STRICT_OBIT_USAGE_CHECK
1514 if ((IS_OPAQUE_LSA(lsah->type) &&
1515 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1516 || (! IS_OPAQUE_LSA(lsah->type) &&
1517 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1518 {
1519 /*
1520 * This neighbor must know the exact usage of O-bit;
1521 * the bit will be set in Type-9,10,11 LSAs only.
1522 */
1523 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1524 continue;
1525 }
1526#endif /* STRICT_OBIT_USAGE_CHECK */
1527
1528 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1529 if (lsah->type == OSPF_OPAQUE_AS_LSA
1530 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1531 {
1532 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001533 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 +00001534 continue;
1535 }
1536 }
1537 else if (IS_OPAQUE_LSA(lsah->type))
1538 {
1539 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1540 continue;
1541 }
1542#endif /* HAVE_OPAQUE_LSA */
1543
1544 /* Create OSPF LSA instance. */
1545 lsa = ospf_lsa_new ();
1546
1547 /* We may wish to put some error checking if type NSSA comes in
1548 and area not in NSSA mode */
1549 switch (lsah->type)
1550 {
1551 case OSPF_AS_EXTERNAL_LSA:
1552#ifdef HAVE_OPAQUE_LSA
1553 case OSPF_OPAQUE_AS_LSA:
1554 lsa->area = NULL;
1555 break;
1556 case OSPF_OPAQUE_LINK_LSA:
1557 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1558 /* Fallthrough */
1559#endif /* HAVE_OPAQUE_LSA */
1560 default:
1561 lsa->area = oi->area;
1562 break;
1563 }
1564
1565 lsa->data = ospf_lsa_data_new (length);
1566 memcpy (lsa->data, lsah, length);
1567
1568 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001569 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001570 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1571 listnode_add (lsas, lsa);
1572 }
1573
1574 return lsas;
1575}
1576
1577/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001578static void
hasso52dc7ee2004-09-23 19:18:23 +00001579ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001580{
paul1eb8ef22005-04-07 07:30:20 +00001581 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001582 struct ospf_lsa *lsa;
1583
paul1eb8ef22005-04-07 07:30:20 +00001584 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1585 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001586
1587 list_delete (lsas);
1588}
1589
1590/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001591static void
paul718e3742002-12-13 20:15:29 +00001592ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1593 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1594{
1595 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001596 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001597 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001598 struct ospf_lsa *lsa = NULL;
1599 /* unsigned long ls_req_found = 0; */
1600
1601 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1602
1603 /* Increment statistics. */
1604 oi->ls_upd_in++;
1605
1606 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001607 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001608 if (nbr == NULL)
1609 {
1610 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1611 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1612 return;
1613 }
1614
1615 /* Check neighbor state. */
1616 if (nbr->state < NSM_Exchange)
1617 {
ajs3aa8d5f2004-12-11 18:00:06 +00001618 zlog_warn ("Link State Update: "
1619 "Neighbor[%s] state %s is less than Exchange",
1620 inet_ntoa (ospfh->router_id),
1621 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001622 return;
1623 }
1624
1625 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1626 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1627 * of section 13.
1628 */
1629 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1630
1631#ifdef HAVE_OPAQUE_LSA
1632 /*
paul718e3742002-12-13 20:15:29 +00001633 * If self-originated Opaque-LSAs that have flooded before restart
1634 * are contained in the received LSUpd message, corresponding LSReq
1635 * messages to be sent may have to be modified.
1636 * To eliminate possible race conditions such that flushing and normal
1637 * updating for the same LSA would take place alternately, this trick
1638 * must be done before entering to the loop below.
1639 */
paul69310a62005-05-11 18:09:59 +00001640 /* XXX: Why is this Opaque specific? Either our core code is deficient
1641 * and this should be fixed generally, or Opaque is inventing strawman
1642 * problems */
paul718e3742002-12-13 20:15:29 +00001643 ospf_opaque_adjust_lsreq (nbr, lsas);
1644#endif /* HAVE_OPAQUE_LSA */
1645
1646#define DISCARD_LSA(L,N) {\
1647 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001648 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 +00001649 ospf_lsa_discard (L); \
1650 continue; }
1651
1652 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001653 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001654 {
1655 struct ospf_lsa *ls_ret, *current;
1656 int ret = 1;
1657
paul718e3742002-12-13 20:15:29 +00001658 if (IS_DEBUG_OSPF_NSSA)
1659 {
1660 char buf1[INET_ADDRSTRLEN];
1661 char buf2[INET_ADDRSTRLEN];
1662 char buf3[INET_ADDRSTRLEN];
1663
ajs2a42e282004-12-08 18:43:03 +00001664 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001665 lsa->data->type,
1666 inet_ntop (AF_INET, &ospfh->router_id,
1667 buf1, INET_ADDRSTRLEN),
1668 inet_ntop (AF_INET, &lsa->data->id,
1669 buf2, INET_ADDRSTRLEN),
1670 inet_ntop (AF_INET, &lsa->data->adv_router,
1671 buf3, INET_ADDRSTRLEN));
1672 }
paul718e3742002-12-13 20:15:29 +00001673
1674 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1675
1676 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1677
1678 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1679
1680 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1681
1682 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1683
1684 /* Do take in Type-7's if we are an NSSA */
1685
1686 /* If we are also an ABR, later translate them to a Type-5 packet */
1687
1688 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1689 translate them to a separate Type-5 packet. */
1690
1691 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1692 /* Reject from STUB or NSSA */
1693 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1694 {
1695 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001696 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001697 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001698 }
1699
paul718e3742002-12-13 20:15:29 +00001700 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1701 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1702 {
1703 DISCARD_LSA (lsa,2);
1704 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001705 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001706 }
paul718e3742002-12-13 20:15:29 +00001707
1708 /* Find the LSA in the current database. */
1709
1710 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1711
1712 /* If the LSA's LS age is equal to MaxAge, and there is currently
1713 no instance of the LSA in the router's link state database,
1714 and none of router's neighbors are in states Exchange or Loading,
1715 then take the following actions. */
1716
1717 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001718 (ospf_nbr_count (oi, NSM_Exchange) +
1719 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001720 {
1721 /* Response Link State Acknowledgment. */
1722 ospf_ls_ack_send (nbr, lsa);
1723
1724 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001725 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1726 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001727 DISCARD_LSA (lsa, 3);
1728 }
1729
1730#ifdef HAVE_OPAQUE_LSA
1731 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001732 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001733 {
1734 /*
1735 * Even if initial flushing seems to be completed, there might
1736 * be a case that self-originated LSA with MaxAge still remain
1737 * in the routing domain.
1738 * Just send an LSAck message to cease retransmission.
1739 */
1740 if (IS_LSA_MAXAGE (lsa))
1741 {
1742 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1743 ospf_ls_ack_send (nbr, lsa);
1744 ospf_lsa_discard (lsa);
1745
1746 if (current != NULL && ! IS_LSA_MAXAGE (current))
1747 ospf_opaque_lsa_refresh_schedule (current);
1748 continue;
1749 }
1750
1751 /*
1752 * If an instance of self-originated Opaque-LSA is not found
1753 * in the LSDB, there are some possible cases here.
1754 *
1755 * 1) This node lost opaque-capability after restart.
1756 * 2) Else, a part of opaque-type is no more supported.
1757 * 3) Else, a part of opaque-id is no more supported.
1758 *
1759 * Anyway, it is still this node's responsibility to flush it.
1760 * Otherwise, the LSA instance remains in the routing domain
1761 * until its age reaches to MaxAge.
1762 */
paul69310a62005-05-11 18:09:59 +00001763 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001764 if (current == NULL)
1765 {
1766 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001767 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1768 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001769
1770 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001771
1772 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1773 ospf_ls_ack_send (nbr, lsa);
1774
paul718e3742002-12-13 20:15:29 +00001775 continue;
1776 }
1777 }
1778#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001779
hassocb05eb22004-02-11 21:10:19 +00001780 /* It might be happen that received LSA is self-originated network LSA, but
1781 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1782 * Link State ID is one of the router's own IP interface addresses but whose
1783 * Advertising Router is not equal to the router's own Router ID
1784 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1785 */
1786
1787 if(lsa->data->type == OSPF_NETWORK_LSA)
1788 {
paul1eb8ef22005-04-07 07:30:20 +00001789 struct listnode *oinode, *oinnode;
1790 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001791 int Flag = 0;
1792
paul1eb8ef22005-04-07 07:30:20 +00001793 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001794 {
hassocb05eb22004-02-11 21:10:19 +00001795 if(out_if == NULL)
1796 break;
1797
1798 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1799 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1800 {
1801 if(out_if->network_lsa_self)
1802 {
1803 ospf_lsa_flush_area(lsa,out_if->area);
1804 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001805 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001806 lsa, (int) lsa->data->type);
1807 ospf_lsa_discard (lsa);
1808 Flag = 1;
1809 }
1810 break;
1811 }
1812 }
1813 if(Flag)
1814 continue;
1815 }
paul718e3742002-12-13 20:15:29 +00001816
1817 /* (5) Find the instance of this LSA that is currently contained
1818 in the router's link state database. If there is no
1819 database copy, or the received LSA is more recent than
1820 the database copy the following steps must be performed. */
1821
1822 if (current == NULL ||
1823 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1824 {
1825 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001826 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001827 DISCARD_LSA (lsa, 4);
1828 continue;
1829 }
1830
1831 /* (6) Else, If there is an instance of the LSA on the sending
1832 neighbor's Link state request list, an error has occurred in
1833 the Database Exchange process. In this case, restart the
1834 Database Exchange process by generating the neighbor event
1835 BadLSReq for the sending neighbor and stop processing the
1836 Link State Update packet. */
1837
1838 if (ospf_ls_request_lookup (nbr, lsa))
1839 {
1840 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001841 zlog_warn("LSA[%s] instance exists on Link state request list",
1842 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001843
1844 /* Clean list of LSAs. */
1845 ospf_upd_list_clean (lsas);
1846 /* this lsa is not on lsas list already. */
1847 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001848 return;
1849 }
1850
1851 /* If the received LSA is the same instance as the database copy
1852 (i.e., neither one is more recent) the following two steps
1853 should be performed: */
1854
1855 if (ret == 0)
1856 {
1857 /* If the LSA is listed in the Link state retransmission list
1858 for the receiving adjacency, the router itself is expecting
1859 an acknowledgment for this LSA. The router should treat the
1860 received LSA as an acknowledgment by removing the LSA from
1861 the Link state retransmission list. This is termed an
1862 "implied acknowledgment". */
1863
1864 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1865
1866 if (ls_ret != NULL)
1867 {
1868 ospf_ls_retransmit_delete (nbr, ls_ret);
1869
1870 /* Delayed acknowledgment sent if advertisement received
1871 from Designated Router, otherwise do nothing. */
1872 if (oi->state == ISM_Backup)
1873 if (NBR_IS_DR (nbr))
1874 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1875
1876 DISCARD_LSA (lsa, 5);
1877 }
1878 else
1879 /* Acknowledge the receipt of the LSA by sending a
1880 Link State Acknowledgment packet back out the receiving
1881 interface. */
1882 {
1883 ospf_ls_ack_send (nbr, lsa);
1884 DISCARD_LSA (lsa, 6);
1885 }
1886 }
1887
1888 /* The database copy is more recent. If the database copy
1889 has LS age equal to MaxAge and LS sequence number equal to
1890 MaxSequenceNumber, simply discard the received LSA without
1891 acknowledging it. (In this case, the LSA's LS sequence number is
1892 wrapping, and the MaxSequenceNumber LSA must be completely
1893 flushed before any new LSA instance can be introduced). */
1894
1895 else if (ret > 0) /* Database copy is more recent */
1896 {
1897 if (IS_LSA_MAXAGE (current) &&
1898 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1899 {
1900 DISCARD_LSA (lsa, 7);
1901 }
1902 /* Otherwise, as long as the database copy has not been sent in a
1903 Link State Update within the last MinLSArrival seconds, send the
1904 database copy back to the sending neighbor, encapsulated within
1905 a Link State Update Packet. The Link State Update Packet should
1906 be sent directly to the neighbor. In so doing, do not put the
1907 database copy of the LSA on the neighbor's link state
1908 retransmission list, and do not acknowledge the received (less
1909 recent) LSA instance. */
1910 else
1911 {
1912 struct timeval now;
1913
1914 gettimeofday (&now, NULL);
1915
1916 if (tv_cmp (tv_sub (now, current->tv_orig),
1917 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1918 /* Trap NSSA type later.*/
1919 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1920 DISCARD_LSA (lsa, 8);
1921 }
1922 }
1923 }
1924
paul718e3742002-12-13 20:15:29 +00001925 assert (listcount (lsas) == 0);
1926 list_delete (lsas);
1927}
1928
1929/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001930static void
paul718e3742002-12-13 20:15:29 +00001931ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1932 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1933{
1934 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001935
paul718e3742002-12-13 20:15:29 +00001936 /* increment statistics. */
1937 oi->ls_ack_in++;
1938
pauld3f0d622004-05-05 15:27:15 +00001939 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001940 if (nbr == NULL)
1941 {
1942 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1943 inet_ntoa (ospfh->router_id));
1944 return;
1945 }
1946
1947 if (nbr->state < NSM_Exchange)
1948 {
ajs3aa8d5f2004-12-11 18:00:06 +00001949 zlog_warn ("Link State Acknowledgment: "
1950 "Neighbor[%s] state %s is less than Exchange",
1951 inet_ntoa (ospfh->router_id),
1952 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001953 return;
1954 }
paul69310a62005-05-11 18:09:59 +00001955
paul718e3742002-12-13 20:15:29 +00001956 while (size >= OSPF_LSA_HEADER_SIZE)
1957 {
1958 struct ospf_lsa *lsa, *lsr;
1959
1960 lsa = ospf_lsa_new ();
1961 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1962
1963 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1964 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00001965 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001966
1967 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1968 {
1969 lsa->data = NULL;
1970 ospf_lsa_discard (lsa);
1971 continue;
1972 }
1973
1974 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1975
1976 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1977 {
1978#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001979 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00001980 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00001981#endif /* HAVE_OPAQUE_LSA */
1982
1983 ospf_ls_retransmit_delete (nbr, lsr);
1984 }
1985
1986 lsa->data = NULL;
1987 ospf_lsa_discard (lsa);
1988 }
1989
paul718e3742002-12-13 20:15:29 +00001990 return;
paul718e3742002-12-13 20:15:29 +00001991}
1992
ajs038163f2005-02-17 19:55:59 +00001993static struct stream *
ajs5c333492005-02-23 15:43:01 +00001994ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00001995{
1996 int ret;
ajs5c333492005-02-23 15:43:01 +00001997 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00001998 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00001999 unsigned int ifindex = 0;
2000 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002001 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002002 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002003 struct msghdr msgh;
2004
paul68defd62004-09-27 07:27:13 +00002005 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002006 msgh.msg_iov = &iov;
2007 msgh.msg_iovlen = 1;
2008 msgh.msg_control = (caddr_t) buff;
2009 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002010
ajs5c333492005-02-23 15:43:01 +00002011 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2012 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002013 {
ajs5c333492005-02-23 15:43:01 +00002014 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2015 return NULL;
2016 }
paul69310a62005-05-11 18:09:59 +00002017 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002018 {
2019 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2020 "(ip header size is %u)",
2021 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002022 return NULL;
2023 }
paul18b12c32004-10-05 14:38:29 +00002024
ajs5c333492005-02-23 15:43:01 +00002025 /* Note that there should not be alignment problems with this assignment
2026 because this is at the beginning of the stream data buffer. */
2027 iph = (struct ip *) STREAM_DATA(ibuf);
2028 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002029
ajs5c333492005-02-23 15:43:01 +00002030 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002031
paul239aecc2003-12-08 10:34:54 +00002032#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002033 /*
2034 * Kernel network code touches incoming IP header parameters,
2035 * before protocol specific processing.
2036 *
2037 * 1) Convert byteorder to host representation.
2038 * --> ip_len, ip_id, ip_off
2039 *
2040 * 2) Adjust ip_len to strip IP header size!
2041 * --> If user process receives entire IP packet via RAW
2042 * socket, it must consider adding IP header size to
2043 * the "ip_len" field of "ip" structure.
2044 *
2045 * For more details, see <netinet/ip_input.c>.
2046 */
ajs5c333492005-02-23 15:43:01 +00002047 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002048#endif
2049
paul863082d2004-08-19 04:43:43 +00002050 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002051
2052 *ifp = if_lookup_by_index (ifindex);
2053
2054 if (ret != ip_len)
2055 {
ajs5c333492005-02-23 15:43:01 +00002056 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2057 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002058 return NULL;
2059 }
2060
2061 return ibuf;
2062}
2063
paul4dadc292005-05-06 21:37:42 +00002064static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002065ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002066 struct ip *iph, struct ospf_header *ospfh)
2067{
2068 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002069 struct ospf_vl_data *vl_data;
2070 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002071 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002072
2073 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2074 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002075 return NULL;
paul718e3742002-12-13 20:15:29 +00002076
pauld3f0d622004-05-05 15:27:15 +00002077 /* look for local OSPF interface matching the destination
2078 * to determine Area ID. We presume therefore the destination address
2079 * is unique, or at least (for "unnumbered" links), not used in other
2080 * areas
2081 */
2082 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2083 iph->ip_dst)) == NULL)
2084 return NULL;
paul718e3742002-12-13 20:15:29 +00002085
paul1eb8ef22005-04-07 07:30:20 +00002086 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002087 {
paul020709f2003-04-04 02:44:16 +00002088 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002089 if (!vl_area)
2090 continue;
2091
2092 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2093 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2094 {
2095 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002096 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002097 IF_NAME (vl_data->vl_oi));
2098 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2099 {
2100 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002101 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002102 return NULL;
2103 }
2104
2105 return vl_data->vl_oi;
2106 }
2107 }
2108
2109 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002110 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002111
pauld3f0d622004-05-05 15:27:15 +00002112 return NULL;
paul718e3742002-12-13 20:15:29 +00002113}
2114
paul4dadc292005-05-06 21:37:42 +00002115static inline int
paul718e3742002-12-13 20:15:29 +00002116ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2117{
2118 /* Check match the Area ID of the receiving interface. */
2119 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2120 return 1;
2121
2122 return 0;
2123}
2124
2125/* Unbound socket will accept any Raw IP packets if proto is matched.
2126 To prevent it, compare src IP address and i/f address with masking
2127 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002128static int
paul718e3742002-12-13 20:15:29 +00002129ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2130{
2131 struct in_addr mask, me, him;
2132
2133 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2134 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2135 return 1;
2136
2137 masklen2ip (oi->address->prefixlen, &mask);
2138
2139 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2140 him.s_addr = ip_src.s_addr & mask.s_addr;
2141
2142 if (IPV4_ADDR_SAME (&me, &him))
2143 return 1;
2144
2145 return 0;
2146}
2147
paul4dadc292005-05-06 21:37:42 +00002148static int
paul718e3742002-12-13 20:15:29 +00002149ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2150 struct ospf_header *ospfh)
2151{
2152 int ret = 0;
2153 struct crypt_key *ck;
2154
2155 switch (ntohs (ospfh->auth_type))
2156 {
2157 case OSPF_AUTH_NULL:
2158 ret = 1;
2159 break;
2160 case OSPF_AUTH_SIMPLE:
2161 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2162 ret = 1;
2163 else
2164 ret = 0;
2165 break;
2166 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002167 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002168 {
2169 ret = 0;
2170 break;
2171 }
2172
2173 /* This is very basic, the digest processing is elsewhere */
2174 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2175 ospfh->u.crypt.key_id == ck->key_id &&
2176 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2177 ret = 1;
2178 else
2179 ret = 0;
2180 break;
2181 default:
2182 ret = 0;
2183 break;
2184 }
2185
2186 return ret;
2187}
2188
paul4dadc292005-05-06 21:37:42 +00002189static int
paul718e3742002-12-13 20:15:29 +00002190ospf_check_sum (struct ospf_header *ospfh)
2191{
2192 u_int32_t ret;
2193 u_int16_t sum;
2194 int in_cksum (void *ptr, int nbytes);
2195
2196 /* clear auth_data for checksum. */
2197 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2198
2199 /* keep checksum and clear. */
2200 sum = ospfh->checksum;
2201 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2202
2203 /* calculate checksum. */
2204 ret = in_cksum (ospfh, ntohs (ospfh->length));
2205
2206 if (ret != sum)
2207 {
2208 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2209 ret, sum);
2210 return 0;
2211 }
2212
2213 return 1;
2214}
2215
2216/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002217static int
paul718e3742002-12-13 20:15:29 +00002218ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2219 struct ip *iph, struct ospf_header *ospfh)
2220{
2221 /* check version. */
2222 if (ospfh->version != OSPF_VERSION)
2223 {
2224 zlog_warn ("interface %s: ospf_read version number mismatch.",
2225 IF_NAME (oi));
2226 return -1;
2227 }
2228
2229 /* Check Area ID. */
2230 if (!ospf_check_area_id (oi, ospfh))
2231 {
2232 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2233 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2234 return -1;
2235 }
2236
2237 /* Check network mask, Silently discarded. */
2238 if (! ospf_check_network_mask (oi, iph->ip_src))
2239 {
2240 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2241 IF_NAME (oi), inet_ntoa (iph->ip_src));
2242 return -1;
2243 }
2244
2245 /* Check authentication. */
2246 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2247 {
2248 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2249 IF_NAME (oi));
2250 return -1;
2251 }
2252
2253 if (! ospf_check_auth (oi, ibuf, ospfh))
2254 {
2255 zlog_warn ("interface %s: ospf_read authentication failed.",
2256 IF_NAME (oi));
2257 return -1;
2258 }
2259
2260 /* if check sum is invalid, packet is discarded. */
2261 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2262 {
2263 if (! ospf_check_sum (ospfh))
2264 {
2265 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2266 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2267 return -1;
2268 }
2269 }
2270 else
2271 {
2272 if (ospfh->checksum != 0)
2273 return -1;
2274 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2275 {
2276 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2277 IF_NAME (oi));
2278 return -1;
2279 }
2280 }
2281
2282 return 0;
2283}
2284
2285/* Starting point of packet process function. */
2286int
2287ospf_read (struct thread *thread)
2288{
2289 int ret;
2290 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002291 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002292 struct ospf_interface *oi;
2293 struct ip *iph;
2294 struct ospf_header *ospfh;
2295 u_int16_t length;
2296 struct interface *ifp;
2297
2298 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002299 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002300
2301 /* prepare for next packet. */
2302 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002303
2304 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002305 stream_reset(ospf->ibuf);
2306 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002307 return -1;
2308
ajs5c333492005-02-23 15:43:01 +00002309 /* Note that there should not be alignment problems with this assignment
2310 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002311 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002312 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002313
paulac191232004-10-22 12:05:17 +00002314 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002315 /* Handle cases where the platform does not support retrieving the ifindex,
2316 and also platforms (such as Solaris 8) that claim to support ifindex
2317 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002318 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002319
pauld3f0d622004-05-05 15:27:15 +00002320 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002321 return 0;
paul718e3742002-12-13 20:15:29 +00002322
2323 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002324 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002325 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002326
paul718e3742002-12-13 20:15:29 +00002327 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002328 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002329 {
pauld3241812003-09-29 12:42:39 +00002330 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2331 {
ajs2a42e282004-12-08 18:43:03 +00002332 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002333 inet_ntoa (iph->ip_src));
2334 }
paul718e3742002-12-13 20:15:29 +00002335 return 0;
2336 }
2337
2338 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002339 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002340
2341 /* Get ospf packet header. */
2342 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2343
2344 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002345 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002346
2347 /* if no local ospf_interface,
2348 * or header area is backbone but ospf_interface is not
2349 * check for VLINK interface
2350 */
2351 if ( (oi == NULL) ||
2352 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2353 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2354 )
2355 {
2356 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2357 {
2358 zlog_warn ("Packet from [%s] received on link %s"
2359 " but no ospf_interface",
2360 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002361 return 0;
2362 }
2363 }
2364
2365 /* else it must be a local ospf interface, check it was received on
2366 * correct link
2367 */
2368 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002369 {
2370 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002371 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002372 return 0;
2373 }
ajs847947f2005-02-02 18:38:48 +00002374 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002375 {
ajsba6454e2005-02-08 15:37:30 +00002376 char buf[2][INET_ADDRSTRLEN];
2377 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002378 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002379 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2380 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2381 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002382 /* Fix multicast memberships? */
2383 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2384 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2385 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2386 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2387 if (oi->multicast_memberships)
2388 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002389 return 0;
2390 }
paul718e3742002-12-13 20:15:29 +00002391
2392 /*
2393 * If the received packet is destined for AllDRouters, the packet
2394 * should be accepted only if the received ospf interface state is
2395 * either DR or Backup -- endo.
2396 */
2397 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2398 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2399 {
ajsba6454e2005-02-08 15:37:30 +00002400 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002401 inet_ntoa (iph->ip_src), IF_NAME (oi),
2402 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002403 /* Try to fix multicast membership. */
2404 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2405 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002406 return 0;
2407 }
2408
2409 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002410 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2411 {
paul718e3742002-12-13 20:15:29 +00002412 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002413 {
ajs2a42e282004-12-08 18:43:03 +00002414 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002415 ospf_packet_dump (ibuf);
2416 }
paul718e3742002-12-13 20:15:29 +00002417
ajs2a42e282004-12-08 18:43:03 +00002418 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002419 ospf_packet_type_str[ospfh->type],
2420 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002421 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2422 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002423
2424 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002425 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002426 }
paul718e3742002-12-13 20:15:29 +00002427
2428 /* Some header verification. */
2429 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2430 if (ret < 0)
2431 {
pauld3241812003-09-29 12:42:39 +00002432 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2433 {
ajs2a42e282004-12-08 18:43:03 +00002434 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002435 "dropping.",
2436 ospf_packet_type_str[ospfh->type],
2437 inet_ntoa (iph->ip_src));
2438 }
paul718e3742002-12-13 20:15:29 +00002439 return ret;
2440 }
2441
paul9985f832005-02-09 15:51:56 +00002442 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002443
2444 /* Adjust size to message length. */
2445 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2446
2447 /* Read rest of the packet and call each sort of packet routine. */
2448 switch (ospfh->type)
2449 {
2450 case OSPF_MSG_HELLO:
2451 ospf_hello (iph, ospfh, ibuf, oi, length);
2452 break;
2453 case OSPF_MSG_DB_DESC:
2454 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2455 break;
2456 case OSPF_MSG_LS_REQ:
2457 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2458 break;
2459 case OSPF_MSG_LS_UPD:
2460 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2461 break;
2462 case OSPF_MSG_LS_ACK:
2463 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2464 break;
2465 default:
2466 zlog (NULL, LOG_WARNING,
2467 "interface %s: OSPF packet header type %d is illegal",
2468 IF_NAME (oi), ospfh->type);
2469 break;
2470 }
2471
paul718e3742002-12-13 20:15:29 +00002472 return 0;
2473}
2474
2475/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002476static void
paul718e3742002-12-13 20:15:29 +00002477ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2478{
2479 struct ospf_header *ospfh;
2480
2481 ospfh = (struct ospf_header *) STREAM_DATA (s);
2482
2483 ospfh->version = (u_char) OSPF_VERSION;
2484 ospfh->type = (u_char) type;
2485
paul68980082003-03-25 05:07:42 +00002486 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002487
2488 ospfh->checksum = 0;
2489 ospfh->area_id = oi->area->area_id;
2490 ospfh->auth_type = htons (ospf_auth_type (oi));
2491
2492 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2493
paul9985f832005-02-09 15:51:56 +00002494 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002495}
2496
2497/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002498static int
paul718e3742002-12-13 20:15:29 +00002499ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2500{
2501 struct crypt_key *ck;
2502
2503 switch (ospf_auth_type (oi))
2504 {
2505 case OSPF_AUTH_NULL:
2506 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2507 break;
2508 case OSPF_AUTH_SIMPLE:
2509 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2510 OSPF_AUTH_SIMPLE_SIZE);
2511 break;
2512 case OSPF_AUTH_CRYPTOGRAPHIC:
2513 /* If key is not set, then set 0. */
2514 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2515 {
2516 ospfh->u.crypt.zero = 0;
2517 ospfh->u.crypt.key_id = 0;
2518 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2519 }
2520 else
2521 {
paul1eb8ef22005-04-07 07:30:20 +00002522 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002523 ospfh->u.crypt.zero = 0;
2524 ospfh->u.crypt.key_id = ck->key_id;
2525 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2526 }
2527 /* note: the seq is done in ospf_make_md5_digest() */
2528 break;
2529 default:
2530 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2531 break;
2532 }
2533
2534 return 0;
2535}
2536
2537/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002538static void
paul718e3742002-12-13 20:15:29 +00002539ospf_fill_header (struct ospf_interface *oi,
2540 struct stream *s, u_int16_t length)
2541{
2542 struct ospf_header *ospfh;
2543
2544 ospfh = (struct ospf_header *) STREAM_DATA (s);
2545
2546 /* Fill length. */
2547 ospfh->length = htons (length);
2548
2549 /* Calculate checksum. */
2550 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2551 ospfh->checksum = in_cksum (ospfh, length);
2552 else
2553 ospfh->checksum = 0;
2554
2555 /* Add Authentication Data. */
2556 ospf_make_auth (oi, ospfh);
2557}
2558
paul4dadc292005-05-06 21:37:42 +00002559static int
paul718e3742002-12-13 20:15:29 +00002560ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2561{
2562 struct ospf_neighbor *nbr;
2563 struct route_node *rn;
2564 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2565 struct in_addr mask;
2566 unsigned long p;
2567 int flag = 0;
2568
2569 /* Set netmask of interface. */
2570 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2571 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2572 masklen2ip (oi->address->prefixlen, &mask);
2573 else
2574 memset ((char *) &mask, 0, sizeof (struct in_addr));
2575 stream_put_ipv4 (s, mask.s_addr);
2576
2577 /* Set Hello Interval. */
2578 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2579
2580 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002581 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002582 OPTIONS(oi), IF_NAME (oi));
2583
2584 /* Set Options. */
2585 stream_putc (s, OPTIONS (oi));
2586
2587 /* Set Router Priority. */
2588 stream_putc (s, PRIORITY (oi));
2589
2590 /* Set Router Dead Interval. */
2591 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2592
2593 /* Set Designated Router. */
2594 stream_put_ipv4 (s, DR (oi).s_addr);
2595
paul9985f832005-02-09 15:51:56 +00002596 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002597
2598 /* Set Backup Designated Router. */
2599 stream_put_ipv4 (s, BDR (oi).s_addr);
2600
2601 /* Add neighbor seen. */
2602 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002603 if ((nbr = rn->info))
2604 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2605 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2606 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2607 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002608 {
2609 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002610 if (nbr->d_router.s_addr != 0
2611 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2612 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2613 flag = 1;
paul718e3742002-12-13 20:15:29 +00002614
2615 stream_put_ipv4 (s, nbr->router_id.s_addr);
2616 length += 4;
2617 }
2618
2619 /* Let neighbor generate BackupSeen. */
2620 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002621 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002622
2623 return length;
2624}
2625
paul4dadc292005-05-06 21:37:42 +00002626static int
paul718e3742002-12-13 20:15:29 +00002627ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2628 struct stream *s)
2629{
2630 struct ospf_lsa *lsa;
2631 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2632 u_char options;
2633 unsigned long pp;
2634 int i;
2635 struct ospf_lsdb *lsdb;
2636
2637 /* Set Interface MTU. */
2638 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2639 stream_putw (s, 0);
2640 else
2641 stream_putw (s, oi->ifp->mtu);
2642
2643 /* Set Options. */
2644 options = OPTIONS (oi);
2645#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002646 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002647 {
2648 if (IS_SET_DD_I (nbr->dd_flags)
2649 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2650 /*
2651 * Set O-bit in the outgoing DD packet for capablity negotiation,
2652 * if one of following case is applicable.
2653 *
2654 * 1) WaitTimer expiration event triggered the neighbor state to
2655 * change to Exstart, but no (valid) DD packet has received
2656 * from the neighbor yet.
2657 *
2658 * 2) At least one DD packet with O-bit on has received from the
2659 * neighbor.
2660 */
2661 SET_FLAG (options, OSPF_OPTION_O);
2662 }
2663#endif /* HAVE_OPAQUE_LSA */
2664 stream_putc (s, options);
2665
2666 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002667 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002668 stream_putc (s, nbr->dd_flags);
2669
2670 /* Set DD Sequence Number. */
2671 stream_putl (s, nbr->dd_seqnum);
2672
2673 if (ospf_db_summary_isempty (nbr))
2674 {
2675 if (nbr->state >= NSM_Exchange)
2676 {
2677 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2678 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002679 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002680 }
2681 return length;
2682 }
2683
2684 /* Describe LSA Header from Database Summary List. */
2685 lsdb = &nbr->db_sum;
2686
2687 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2688 {
2689 struct route_table *table = lsdb->type[i].db;
2690 struct route_node *rn;
2691
2692 for (rn = route_top (table); rn; rn = route_next (rn))
2693 if ((lsa = rn->info) != NULL)
2694 {
2695#ifdef HAVE_OPAQUE_LSA
2696 if (IS_OPAQUE_LSA (lsa->data->type)
2697 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2698 {
2699 /* Suppress advertising opaque-informations. */
2700 /* Remove LSA from DB summary list. */
2701 ospf_lsdb_delete (lsdb, lsa);
2702 continue;
2703 }
2704#endif /* HAVE_OPAQUE_LSA */
2705
2706 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2707 {
2708 struct lsa_header *lsah;
2709 u_int16_t ls_age;
2710
2711 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002712 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002713 break;
2714
2715 /* Keep pointer to LS age. */
2716 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002717 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002718
2719 /* Proceed stream pointer. */
2720 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2721 length += OSPF_LSA_HEADER_SIZE;
2722
2723 /* Set LS age. */
2724 ls_age = LS_AGE (lsa);
2725 lsah->ls_age = htons (ls_age);
2726
2727 }
2728
2729 /* Remove LSA from DB summary list. */
2730 ospf_lsdb_delete (lsdb, lsa);
2731 }
2732 }
2733
2734 return length;
2735}
2736
paul4dadc292005-05-06 21:37:42 +00002737static int
paul718e3742002-12-13 20:15:29 +00002738ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2739 unsigned long delta, struct ospf_neighbor *nbr,
2740 struct ospf_lsa *lsa)
2741{
2742 struct ospf_interface *oi;
2743
2744 oi = nbr->oi;
2745
2746 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002747 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002748 return 0;
2749
2750 stream_putl (s, lsa->data->type);
2751 stream_put_ipv4 (s, lsa->data->id.s_addr);
2752 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2753
2754 ospf_lsa_unlock (nbr->ls_req_last);
2755 nbr->ls_req_last = ospf_lsa_lock (lsa);
2756
2757 *length += 12;
2758 return 1;
2759}
2760
paul4dadc292005-05-06 21:37:42 +00002761static int
paul718e3742002-12-13 20:15:29 +00002762ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2763{
2764 struct ospf_lsa *lsa;
2765 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002766 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002767 struct route_table *table;
2768 struct route_node *rn;
2769 int i;
2770 struct ospf_lsdb *lsdb;
2771
2772 lsdb = &nbr->ls_req;
2773
2774 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2775 {
2776 table = lsdb->type[i].db;
2777 for (rn = route_top (table); rn; rn = route_next (rn))
2778 if ((lsa = (rn->info)) != NULL)
2779 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2780 {
2781 route_unlock_node (rn);
2782 break;
2783 }
2784 }
2785 return length;
2786}
2787
paul4dadc292005-05-06 21:37:42 +00002788static int
paul718e3742002-12-13 20:15:29 +00002789ls_age_increment (struct ospf_lsa *lsa, int delay)
2790{
2791 int age;
2792
2793 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2794
2795 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2796}
2797
paul4dadc292005-05-06 21:37:42 +00002798static int
hasso52dc7ee2004-09-23 19:18:23 +00002799ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002800{
2801 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002802 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002803 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002804 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002805 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002806 unsigned long pp;
2807 int count = 0;
2808
2809 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002810 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002811
paul9985f832005-02-09 15:51:56 +00002812 pp = stream_get_endp (s);
2813 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002814
gdt86f1fd92005-01-10 14:20:43 +00002815 /* Calculate amount of packet usable for data. */
2816 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2817
paul718e3742002-12-13 20:15:29 +00002818 while ((node = listhead (update)) != NULL)
2819 {
2820 struct lsa_header *lsah;
2821 u_int16_t ls_age;
2822
2823 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002824 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002825
paul1eb8ef22005-04-07 07:30:20 +00002826 lsa = listgetdata (node);
2827
paul718e3742002-12-13 20:15:29 +00002828 assert (lsa->data);
2829
paul68b73392004-09-12 14:21:37 +00002830 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002831 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002832 break;
2833
paul718e3742002-12-13 20:15:29 +00002834 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002835 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002836
2837 /* Put LSA to Link State Request. */
2838 stream_put (s, lsa->data, ntohs (lsa->data->length));
2839
2840 /* Set LS age. */
2841 /* each hop must increment an lsa_age by transmit_delay
2842 of OSPF interface */
2843 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2844 lsah->ls_age = htons (ls_age);
2845
2846 length += ntohs (lsa->data->length);
2847 count++;
2848
2849 list_delete_node (update, node);
2850 ospf_lsa_unlock (lsa);
2851 }
2852
2853 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002854 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002855
2856 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002857 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002858 return length;
2859}
2860
paul4dadc292005-05-06 21:37:42 +00002861static int
hasso52dc7ee2004-09-23 19:18:23 +00002862ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002863{
hasso52dc7ee2004-09-23 19:18:23 +00002864 struct list *rm_list;
2865 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002866 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002867 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002868 struct ospf_lsa *lsa;
2869
2870 rm_list = list_new ();
2871
paul1eb8ef22005-04-07 07:30:20 +00002872 for (ALL_LIST_ELEMENTS_RO (ack, node, lsa))
paul718e3742002-12-13 20:15:29 +00002873 {
paul1eb8ef22005-04-07 07:30:20 +00002874 lsa = listgetdata (node);
paul718e3742002-12-13 20:15:29 +00002875 assert (lsa);
2876
gdt86f1fd92005-01-10 14:20:43 +00002877 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002878 break;
2879
2880 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2881 length += OSPF_LSA_HEADER_SIZE;
2882
2883 listnode_add (rm_list, lsa);
2884 }
2885
2886 /* Remove LSA from LS-Ack list. */
paul1eb8ef22005-04-07 07:30:20 +00002887 /* XXX: this loop should be removed and the list move done in previous
2888 * loop
2889 */
2890 for (ALL_LIST_ELEMENTS_RO (rm_list, node, lsa))
paul718e3742002-12-13 20:15:29 +00002891 {
paul718e3742002-12-13 20:15:29 +00002892 listnode_delete (ack, lsa);
2893 ospf_lsa_unlock (lsa);
2894 }
2895
2896 list_delete (rm_list);
2897
2898 return length;
2899}
2900
2901void
2902ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2903{
2904 struct ospf_packet *op;
2905 u_int16_t length = OSPF_HEADER_SIZE;
2906
2907 op = ospf_packet_new (oi->ifp->mtu);
2908
2909 /* Prepare OSPF common header. */
2910 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2911
2912 /* Prepare OSPF Hello body. */
2913 length += ospf_make_hello (oi, op->s);
2914
2915 /* Fill OSPF header. */
2916 ospf_fill_header (oi, op->s, length);
2917
2918 /* Set packet length. */
2919 op->length = length;
2920
2921 op->dst.s_addr = addr->s_addr;
2922
2923 /* Add packet to the interface output queue. */
2924 ospf_packet_add (oi, op);
2925
2926 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002927 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002928}
2929
paul4dadc292005-05-06 21:37:42 +00002930static void
paul718e3742002-12-13 20:15:29 +00002931ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2932{
2933 struct ospf_interface *oi;
2934
2935 oi = nbr_nbma->oi;
2936 assert(oi);
2937
2938 /* If this is passive interface, do not send OSPF Hello. */
2939 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2940 return;
2941
2942 if (oi->type != OSPF_IFTYPE_NBMA)
2943 return;
2944
2945 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2946 return;
2947
2948 if (PRIORITY(oi) == 0)
2949 return;
2950
2951 if (nbr_nbma->priority == 0
2952 && oi->state != ISM_DR && oi->state != ISM_Backup)
2953 return;
2954
2955 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2956}
2957
2958int
2959ospf_poll_timer (struct thread *thread)
2960{
2961 struct ospf_nbr_nbma *nbr_nbma;
2962
2963 nbr_nbma = THREAD_ARG (thread);
2964 nbr_nbma->t_poll = NULL;
2965
2966 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002967 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002968 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2969
2970 ospf_poll_send (nbr_nbma);
2971
2972 if (nbr_nbma->v_poll > 0)
2973 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2974 nbr_nbma->v_poll);
2975
2976 return 0;
2977}
2978
2979
2980int
2981ospf_hello_reply_timer (struct thread *thread)
2982{
2983 struct ospf_neighbor *nbr;
2984
2985 nbr = THREAD_ARG (thread);
2986 nbr->t_hello_reply = NULL;
2987
2988 assert (nbr->oi);
2989
2990 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002991 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00002992 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2993
2994 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2995
2996 return 0;
2997}
2998
2999/* Send OSPF Hello. */
3000void
3001ospf_hello_send (struct ospf_interface *oi)
3002{
3003 struct ospf_packet *op;
3004 u_int16_t length = OSPF_HEADER_SIZE;
3005
3006 /* If this is passive interface, do not send OSPF Hello. */
3007 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3008 return;
3009
3010 op = ospf_packet_new (oi->ifp->mtu);
3011
3012 /* Prepare OSPF common header. */
3013 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3014
3015 /* Prepare OSPF Hello body. */
3016 length += ospf_make_hello (oi, op->s);
3017
3018 /* Fill OSPF header. */
3019 ospf_fill_header (oi, op->s, length);
3020
3021 /* Set packet length. */
3022 op->length = length;
3023
3024 if (oi->type == OSPF_IFTYPE_NBMA)
3025 {
3026 struct ospf_neighbor *nbr;
3027 struct route_node *rn;
3028
3029 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3030 if ((nbr = rn->info))
3031 if (nbr != oi->nbr_self)
3032 if (nbr->state != NSM_Down)
3033 {
3034 /* RFC 2328 Section 9.5.1
3035 If the router is not eligible to become Designated Router,
3036 it must periodically send Hello Packets to both the
3037 Designated Router and the Backup Designated Router (if they
3038 exist). */
3039 if (PRIORITY(oi) == 0 &&
3040 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3041 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3042 continue;
3043
3044 /* If the router is eligible to become Designated Router, it
3045 must periodically send Hello Packets to all neighbors that
3046 are also eligible. In addition, if the router is itself the
3047 Designated Router or Backup Designated Router, it must also
3048 send periodic Hello Packets to all other neighbors. */
3049
3050 if (nbr->priority == 0 && oi->state == ISM_DROther)
3051 continue;
3052 /* if oi->state == Waiting, send hello to all neighbors */
3053 {
3054 struct ospf_packet *op_dup;
3055
3056 op_dup = ospf_packet_dup(op);
3057 op_dup->dst = nbr->address.u.prefix4;
3058
3059 /* Add packet to the interface output queue. */
3060 ospf_packet_add (oi, op_dup);
3061
paul020709f2003-04-04 02:44:16 +00003062 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003063 }
3064
3065 }
3066 ospf_packet_free (op);
3067 }
3068 else
3069 {
3070 /* Decide destination address. */
3071 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3072 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3073 else
3074 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3075
3076 /* Add packet to the interface output queue. */
3077 ospf_packet_add (oi, op);
3078
3079 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003080 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003081 }
3082}
3083
3084/* Send OSPF Database Description. */
3085void
3086ospf_db_desc_send (struct ospf_neighbor *nbr)
3087{
3088 struct ospf_interface *oi;
3089 struct ospf_packet *op;
3090 u_int16_t length = OSPF_HEADER_SIZE;
3091
3092 oi = nbr->oi;
3093 op = ospf_packet_new (oi->ifp->mtu);
3094
3095 /* Prepare OSPF common header. */
3096 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3097
3098 /* Prepare OSPF Database Description body. */
3099 length += ospf_make_db_desc (oi, nbr, op->s);
3100
3101 /* Fill OSPF header. */
3102 ospf_fill_header (oi, op->s, length);
3103
3104 /* Set packet length. */
3105 op->length = length;
3106
3107 /* Decide destination address. */
3108 op->dst = nbr->address.u.prefix4;
3109
3110 /* Add packet to the interface output queue. */
3111 ospf_packet_add (oi, op);
3112
3113 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003114 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003115
3116 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3117 if (nbr->last_send)
3118 ospf_packet_free (nbr->last_send);
3119 nbr->last_send = ospf_packet_dup (op);
3120 gettimeofday (&nbr->last_send_ts, NULL);
3121}
3122
3123/* Re-send Database Description. */
3124void
3125ospf_db_desc_resend (struct ospf_neighbor *nbr)
3126{
3127 struct ospf_interface *oi;
3128
3129 oi = nbr->oi;
3130
3131 /* Add packet to the interface output queue. */
3132 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3133
3134 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003135 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003136}
3137
3138/* Send Link State Request. */
3139void
3140ospf_ls_req_send (struct ospf_neighbor *nbr)
3141{
3142 struct ospf_interface *oi;
3143 struct ospf_packet *op;
3144 u_int16_t length = OSPF_HEADER_SIZE;
3145
3146 oi = nbr->oi;
3147 op = ospf_packet_new (oi->ifp->mtu);
3148
3149 /* Prepare OSPF common header. */
3150 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3151
3152 /* Prepare OSPF Link State Request body. */
3153 length += ospf_make_ls_req (nbr, op->s);
3154 if (length == OSPF_HEADER_SIZE)
3155 {
3156 ospf_packet_free (op);
3157 return;
3158 }
3159
3160 /* Fill OSPF header. */
3161 ospf_fill_header (oi, op->s, length);
3162
3163 /* Set packet length. */
3164 op->length = length;
3165
3166 /* Decide destination address. */
3167 op->dst = nbr->address.u.prefix4;
3168
3169 /* Add packet to the interface output queue. */
3170 ospf_packet_add (oi, op);
3171
3172 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003173 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003174
3175 /* Add Link State Request Retransmission Timer. */
3176 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3177}
3178
3179/* Send Link State Update with an LSA. */
3180void
3181ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3182 int flag)
3183{
hasso52dc7ee2004-09-23 19:18:23 +00003184 struct list *update;
paul718e3742002-12-13 20:15:29 +00003185
3186 update = list_new ();
3187
3188 listnode_add (update, lsa);
3189 ospf_ls_upd_send (nbr, update, flag);
3190
3191 list_delete (update);
3192}
3193
paul68b73392004-09-12 14:21:37 +00003194/* Determine size for packet. Must be at least big enough to accomodate next
3195 * LSA on list, which may be bigger than MTU size.
3196 *
3197 * Return pointer to new ospf_packet
3198 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3199 * on packet sizes (in which case offending LSA is deleted from update list)
3200 */
3201static struct ospf_packet *
3202ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3203{
3204 struct ospf_lsa *lsa;
3205 struct listnode *ln;
3206 size_t size;
3207 static char warned = 0;
3208
paul1eb8ef22005-04-07 07:30:20 +00003209 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003210 assert (lsa->data);
3211
3212 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3213 > ospf_packet_max (oi))
3214 {
3215 if (!warned)
3216 {
3217 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3218 "will need to fragment. Not optimal. Try divide up"
3219 " your network with areas. Use 'debug ospf packet send'"
3220 " to see details, or look at 'show ip ospf database ..'");
3221 warned = 1;
3222 }
3223
3224 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003225 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003226 " %d bytes originated by %s, will be fragmented!",
3227 inet_ntoa (lsa->data->id),
3228 ntohs (lsa->data->length),
3229 inet_ntoa (lsa->data->adv_router));
3230
3231 /*
3232 * Allocate just enough to fit this LSA only, to avoid including other
3233 * LSAs in fragmented LSA Updates.
3234 */
3235 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3236 + OSPF_LS_UPD_MIN_SIZE;
3237 }
3238 else
3239 size = oi->ifp->mtu;
3240
gdt86f1fd92005-01-10 14:20:43 +00003241 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003242 if (size > OSPF_MAX_PACKET_SIZE)
3243 {
3244 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003245 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003246 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003247 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003248 (long int) size);
paul68b73392004-09-12 14:21:37 +00003249 list_delete_node (update, ln);
3250 return NULL;
3251 }
3252
3253 return ospf_packet_new (size);
3254}
3255
paul718e3742002-12-13 20:15:29 +00003256static void
hasso52dc7ee2004-09-23 19:18:23 +00003257ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003258 struct in_addr addr)
3259{
3260 struct ospf_packet *op;
3261 u_int16_t length = OSPF_HEADER_SIZE;
3262
3263 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003264 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003265
3266 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003267
3268 /* Prepare OSPF common header. */
3269 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3270
paul59ea14c2004-07-14 20:50:36 +00003271 /* Prepare OSPF Link State Update body.
3272 * Includes Type-7 translation.
3273 */
paul718e3742002-12-13 20:15:29 +00003274 length += ospf_make_ls_upd (oi, update, op->s);
3275
3276 /* Fill OSPF header. */
3277 ospf_fill_header (oi, op->s, length);
3278
3279 /* Set packet length. */
3280 op->length = length;
3281
3282 /* Decide destination address. */
3283 op->dst.s_addr = addr.s_addr;
3284
3285 /* Add packet to the interface output queue. */
3286 ospf_packet_add (oi, op);
3287
3288 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003289 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003290}
3291
3292static int
3293ospf_ls_upd_send_queue_event (struct thread *thread)
3294{
3295 struct ospf_interface *oi = THREAD_ARG(thread);
3296 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003297 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003298 struct list *update;
paul68b73392004-09-12 14:21:37 +00003299 char again = 0;
paul718e3742002-12-13 20:15:29 +00003300
3301 oi->t_ls_upd_event = NULL;
3302
3303 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003304 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003305
paul736d3442003-07-24 23:22:57 +00003306 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003307 {
paul736d3442003-07-24 23:22:57 +00003308 rnext = route_next (rn);
3309
paul718e3742002-12-13 20:15:29 +00003310 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003311 continue;
paul68b73392004-09-12 14:21:37 +00003312
3313 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003314
paul48fe13b2004-07-27 17:40:44 +00003315 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003316
paul68b73392004-09-12 14:21:37 +00003317 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003318 if (listcount(update) == 0)
3319 {
3320 list_delete (rn->info);
3321 rn->info = NULL;
3322 route_unlock_node (rn);
3323 }
3324 else
paul68b73392004-09-12 14:21:37 +00003325 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003326 }
3327
3328 if (again != 0)
3329 {
3330 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003331 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003332 " %d nodes to try again, raising new event", again);
3333 oi->t_ls_upd_event =
3334 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003335 }
3336
3337 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003338 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003339
paul718e3742002-12-13 20:15:29 +00003340 return 0;
3341}
3342
3343void
hasso52dc7ee2004-09-23 19:18:23 +00003344ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003345{
3346 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003347 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003348 struct prefix_ipv4 p;
3349 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003350 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003351
3352 oi = nbr->oi;
3353
3354 p.family = AF_INET;
3355 p.prefixlen = IPV4_MAX_BITLEN;
3356
3357 /* Decide destination address. */
3358 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3359 p.prefix = oi->vl_data->peer_addr;
3360 else if (flag == OSPF_SEND_PACKET_DIRECT)
3361 p.prefix = nbr->address.u.prefix4;
3362 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3363 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3364 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3365 && (flag == OSPF_SEND_PACKET_INDIRECT))
3366 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003367 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3368 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003369 else
3370 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3371
3372 if (oi->type == OSPF_IFTYPE_NBMA)
3373 {
3374 if (flag == OSPF_SEND_PACKET_INDIRECT)
3375 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3376 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3377 zlog_warn ("* LS-Update is sent to myself.");
3378 }
3379
3380 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3381
3382 if (rn->info == NULL)
3383 rn->info = list_new ();
3384
paul1eb8ef22005-04-07 07:30:20 +00003385 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3386 {
3387 ospf_lsa_lock (lsa);
3388 listnode_add (rn->info, lsa);
3389 }
paul718e3742002-12-13 20:15:29 +00003390
3391 if (oi->t_ls_upd_event == NULL)
3392 oi->t_ls_upd_event =
3393 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3394}
3395
3396static void
hasso52dc7ee2004-09-23 19:18:23 +00003397ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3398 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003399{
3400 struct ospf_packet *op;
3401 u_int16_t length = OSPF_HEADER_SIZE;
3402
3403 op = ospf_packet_new (oi->ifp->mtu);
3404
3405 /* Prepare OSPF common header. */
3406 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3407
3408 /* Prepare OSPF Link State Acknowledgment body. */
3409 length += ospf_make_ls_ack (oi, ack, op->s);
3410
3411 /* Fill OSPF header. */
3412 ospf_fill_header (oi, op->s, length);
3413
3414 /* Set packet length. */
3415 op->length = length;
3416
3417 /* Set destination IP address. */
3418 op->dst = dst;
3419
3420 /* Add packet to the interface output queue. */
3421 ospf_packet_add (oi, op);
3422
3423 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003424 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003425}
3426
3427static int
3428ospf_ls_ack_send_event (struct thread *thread)
3429{
3430 struct ospf_interface *oi = THREAD_ARG (thread);
3431
3432 oi->t_ls_ack_direct = NULL;
3433
3434 while (listcount (oi->ls_ack_direct.ls_ack))
3435 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3436 oi->ls_ack_direct.dst);
3437
3438 return 0;
3439}
3440
3441void
3442ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3443{
3444 struct ospf_interface *oi = nbr->oi;
3445
3446 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3447 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3448
3449 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3450
3451 if (oi->t_ls_ack_direct == NULL)
3452 oi->t_ls_ack_direct =
3453 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3454}
3455
3456/* Send Link State Acknowledgment delayed. */
3457void
3458ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3459{
3460 struct in_addr dst;
3461
3462 /* Decide destination address. */
3463 /* RFC2328 Section 13.5 On non-broadcast
3464 networks, delayed Link State Acknowledgment packets must be
3465 unicast separately over each adjacency (i.e., neighbor whose
3466 state is >= Exchange). */
3467 if (oi->type == OSPF_IFTYPE_NBMA)
3468 {
3469 struct ospf_neighbor *nbr;
3470 struct route_node *rn;
3471
3472 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3473 if ((nbr = rn->info) != NULL)
3474 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3475 while (listcount (oi->ls_ack))
3476 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3477 return;
3478 }
3479 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3480 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3481 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3482 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3483 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3484 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003485 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3486 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003487 else
3488 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3489
3490 while (listcount (oi->ls_ack))
3491 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3492}