blob: c869d3d808b7e0d301736627c403553fb96ea38c [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. */
vincentba682532005-09-29 13:52:57 +00001114 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1115 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001116 {
ajs3aa8d5f2004-12-11 18:00:06 +00001117 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1118 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1119 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001120 return;
1121 }
1122
pauld363df22003-06-19 00:26:34 +00001123 /*
1124 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1125 * required. In fact at least JunOS sends DD packets with P bit clear.
1126 * Until proper solution is developped, this hack should help.
1127 *
1128 * Update: According to the RFCs, N bit is specified /only/ for Hello
1129 * options, unfortunately its use in DD options is not specified. Hence some
1130 * implementations follow E-bit semantics and set it in DD options, and some
1131 * treat it as unspecified and hence follow the directive "default for
1132 * options is clear", ie unset.
1133 *
1134 * Reset the flag, as ospfd follows E-bit semantics.
1135 */
1136 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1137 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1138 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1139 {
1140 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001141 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001142 inet_ntoa (nbr->router_id) );
1143 SET_FLAG (dd->options, OSPF_OPTION_NP);
1144 }
pauld363df22003-06-19 00:26:34 +00001145
paul718e3742002-12-13 20:15:29 +00001146#ifdef REJECT_IF_TBIT_ON
1147 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1148 {
1149 /*
1150 * In Hello protocol, optional capability must have checked
1151 * to prevent this T-bit enabled router be my neighbor.
1152 */
1153 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1154 return;
1155 }
1156#endif /* REJECT_IF_TBIT_ON */
1157
1158#ifdef HAVE_OPAQUE_LSA
1159 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001160 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001161 {
1162 /*
1163 * This node is not configured to handle O-bit, for now.
1164 * Clear it to ignore unsupported capability proposed by neighbor.
1165 */
1166 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1167 }
1168#endif /* HAVE_OPAQUE_LSA */
1169
1170 /* Process DD packet by neighbor status. */
1171 switch (nbr->state)
1172 {
1173 case NSM_Down:
1174 case NSM_Attempt:
1175 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001176 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001177 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001178 LOOKUP (ospf_nsm_state_msg, nbr->state));
1179 break;
1180 case NSM_Init:
1181 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1182 /* If the new state is ExStart, the processing of the current
1183 packet should then continue in this new state by falling
1184 through to case ExStart below. */
1185 if (nbr->state != NSM_ExStart)
1186 break;
1187 case NSM_ExStart:
1188 /* Initial DBD */
1189 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1190 (size == OSPF_DB_DESC_MIN_SIZE))
1191 {
paul68980082003-03-25 05:07:42 +00001192 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001193 {
1194 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001195 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001196 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001197 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1198 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1199 }
1200 else
1201 {
1202 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001203 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1204 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001205 break;
1206 }
1207 }
1208 /* Ack from the Slave */
1209 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1210 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001211 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001212 {
ajs17eaa722004-12-29 21:04:48 +00001213 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001214 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001215 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1216 }
1217 else
1218 {
ajs3aa8d5f2004-12-11 18:00:06 +00001219 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1220 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001221 break;
1222 }
1223
1224 /* This is where the real Options are saved */
1225 nbr->options = dd->options;
1226
1227#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001228 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001229 {
1230 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001231 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001232 inet_ntoa (nbr->router_id),
1233 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1234
1235 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1236 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1237 {
1238 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1239 /* This situation is undesirable, but not a real error. */
1240 }
1241 }
1242#endif /* HAVE_OPAQUE_LSA */
1243
1244 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1245
1246 /* continue processing rest of packet. */
1247 ospf_db_desc_proc (s, oi, nbr, dd, size);
1248 break;
1249 case NSM_Exchange:
1250 if (ospf_db_desc_is_dup (dd, nbr))
1251 {
1252 if (IS_SET_DD_MS (nbr->dd_flags))
1253 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001254 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1255 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001256 else
1257 /* Slave: cause to retransmit the last Database Description. */
1258 {
ajs3aa8d5f2004-12-11 18:00:06 +00001259 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1260 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001261 ospf_db_desc_resend (nbr);
1262 }
1263 break;
1264 }
1265
1266 /* Otherwise DD packet should be checked. */
1267 /* Check Master/Slave bit mismatch */
1268 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1269 {
ajs3aa8d5f2004-12-11 18:00:06 +00001270 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1271 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001272 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1273 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001274 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001275 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001276 break;
1277 }
1278
1279 /* Check initialize bit is set. */
1280 if (IS_SET_DD_I (dd->flags))
1281 {
ajs3aa8d5f2004-12-11 18:00:06 +00001282 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1283 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001284 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1285 break;
1286 }
1287
1288 /* Check DD Options. */
1289 if (dd->options != nbr->options)
1290 {
1291#ifdef ORIGINAL_CODING
1292 /* Save the new options for debugging */
1293 nbr->options = dd->options;
1294#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001295 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1296 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001297 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1298 break;
1299 }
1300
1301 /* Check DD sequence number. */
1302 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1303 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1304 (!IS_SET_DD_MS (nbr->dd_flags) &&
1305 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1306 {
ajs3aa8d5f2004-12-11 18:00:06 +00001307 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1308 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001309 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1310 break;
1311 }
1312
1313 /* Continue processing rest of packet. */
1314 ospf_db_desc_proc (s, oi, nbr, dd, size);
1315 break;
1316 case NSM_Loading:
1317 case NSM_Full:
1318 if (ospf_db_desc_is_dup (dd, nbr))
1319 {
1320 if (IS_SET_DD_MS (nbr->dd_flags))
1321 {
1322 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001323 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1324 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001325 break;
1326 }
1327 else
1328 {
1329 struct timeval t, now;
1330 gettimeofday (&now, NULL);
1331 t = tv_sub (now, nbr->last_send_ts);
1332 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1333 {
1334 /* In states Loading and Full the slave must resend
1335 its last Database Description packet in response to
1336 duplicate Database Description packets received
1337 from the master. For this reason the slave must
1338 wait RouterDeadInterval seconds before freeing the
1339 last Database Description packet. Reception of a
1340 Database Description packet from the master after
1341 this interval will generate a SeqNumberMismatch
1342 neighbor event. RFC2328 Section 10.8 */
1343 ospf_db_desc_resend (nbr);
1344 break;
1345 }
1346 }
1347 }
1348
1349 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1350 break;
1351 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001352 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1353 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001354 break;
1355 }
1356}
1357
1358#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1359
1360/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001361static void
paul718e3742002-12-13 20:15:29 +00001362ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1363 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1364{
1365 struct ospf_neighbor *nbr;
1366 u_int32_t ls_type;
1367 struct in_addr ls_id;
1368 struct in_addr adv_router;
1369 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001370 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001371 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001372
1373 /* Increment statistics. */
1374 oi->ls_req_in++;
1375
pauld3f0d622004-05-05 15:27:15 +00001376 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001377 if (nbr == NULL)
1378 {
1379 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1380 inet_ntoa (ospfh->router_id));
1381 return;
1382 }
1383
1384 /* Neighbor State should be Exchange or later. */
1385 if (nbr->state != NSM_Exchange &&
1386 nbr->state != NSM_Loading &&
1387 nbr->state != NSM_Full)
1388 {
ajsbec595a2004-11-30 22:38:43 +00001389 zlog_warn ("Link State Request received from %s: "
1390 "Neighbor state is %s, packet discarded.",
1391 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001392 LOOKUP (ospf_nsm_state_msg, nbr->state));
1393 return;
1394 }
1395
1396 /* Send Link State Update for ALL requested LSAs. */
1397 ls_upd = list_new ();
1398 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1399
1400 while (size >= OSPF_LSA_KEY_SIZE)
1401 {
1402 /* Get one slice of Link State Request. */
1403 ls_type = stream_getl (s);
1404 ls_id.s_addr = stream_get_ipv4 (s);
1405 adv_router.s_addr = stream_get_ipv4 (s);
1406
1407 /* Verify LSA type. */
1408 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1409 {
1410 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1411 list_delete (ls_upd);
1412 return;
1413 }
1414
1415 /* Search proper LSA in LSDB. */
1416 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1417 if (find == NULL)
1418 {
1419 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1420 list_delete (ls_upd);
1421 return;
1422 }
1423
gdt86f1fd92005-01-10 14:20:43 +00001424 /* Packet overflows MTU size, send immediately. */
1425 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001426 {
1427 if (oi->type == OSPF_IFTYPE_NBMA)
1428 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1429 else
1430 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1431
1432 /* Only remove list contents. Keep ls_upd. */
1433 list_delete_all_node (ls_upd);
1434
1435 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1436 }
1437
1438 /* Append LSA to update list. */
1439 listnode_add (ls_upd, find);
1440 length += ntohs (find->data->length);
1441
1442 size -= OSPF_LSA_KEY_SIZE;
1443 }
1444
1445 /* Send rest of Link State Update. */
1446 if (listcount (ls_upd) > 0)
1447 {
1448 if (oi->type == OSPF_IFTYPE_NBMA)
1449 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1450 else
1451 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1452
1453 list_delete (ls_upd);
1454 }
1455 else
1456 list_free (ls_upd);
1457}
1458
1459/* Get the list of LSAs from Link State Update packet.
1460 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001461static struct list *
paul718e3742002-12-13 20:15:29 +00001462ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1463 struct ospf_interface *oi, size_t size)
1464{
1465 u_int16_t count, sum;
1466 u_int32_t length;
1467 struct lsa_header *lsah;
1468 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001469 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001470
1471 lsas = list_new ();
1472
1473 count = stream_getl (s);
1474 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1475
1476 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001477 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001478 {
1479 lsah = (struct lsa_header *) STREAM_PNT (s);
1480 length = ntohs (lsah->length);
1481
1482 if (length > size)
1483 {
1484 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1485 break;
1486 }
1487
1488 /* Validate the LSA's LS checksum. */
1489 sum = lsah->checksum;
1490 if (sum != ospf_lsa_checksum (lsah))
1491 {
1492 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1493 sum, lsah->checksum);
1494 continue;
1495 }
1496
1497 /* Examine the LSA's LS type. */
1498 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1499 {
1500 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1501 continue;
1502 }
1503
1504 /*
1505 * What if the received LSA's age is greater than MaxAge?
1506 * Treat it as a MaxAge case -- endo.
1507 */
1508 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1509 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1510
1511#ifdef HAVE_OPAQUE_LSA
1512 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1513 {
1514#ifdef STRICT_OBIT_USAGE_CHECK
1515 if ((IS_OPAQUE_LSA(lsah->type) &&
1516 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1517 || (! IS_OPAQUE_LSA(lsah->type) &&
1518 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1519 {
1520 /*
1521 * This neighbor must know the exact usage of O-bit;
1522 * the bit will be set in Type-9,10,11 LSAs only.
1523 */
1524 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1525 continue;
1526 }
1527#endif /* STRICT_OBIT_USAGE_CHECK */
1528
1529 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1530 if (lsah->type == OSPF_OPAQUE_AS_LSA
1531 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1532 {
1533 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001534 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 +00001535 continue;
1536 }
1537 }
1538 else if (IS_OPAQUE_LSA(lsah->type))
1539 {
1540 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1541 continue;
1542 }
1543#endif /* HAVE_OPAQUE_LSA */
1544
1545 /* Create OSPF LSA instance. */
1546 lsa = ospf_lsa_new ();
1547
1548 /* We may wish to put some error checking if type NSSA comes in
1549 and area not in NSSA mode */
1550 switch (lsah->type)
1551 {
1552 case OSPF_AS_EXTERNAL_LSA:
1553#ifdef HAVE_OPAQUE_LSA
1554 case OSPF_OPAQUE_AS_LSA:
1555 lsa->area = NULL;
1556 break;
1557 case OSPF_OPAQUE_LINK_LSA:
1558 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1559 /* Fallthrough */
1560#endif /* HAVE_OPAQUE_LSA */
1561 default:
1562 lsa->area = oi->area;
1563 break;
1564 }
1565
1566 lsa->data = ospf_lsa_data_new (length);
1567 memcpy (lsa->data, lsah, length);
1568
1569 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001570 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001571 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1572 listnode_add (lsas, lsa);
1573 }
1574
1575 return lsas;
1576}
1577
1578/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001579static void
hasso52dc7ee2004-09-23 19:18:23 +00001580ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001581{
paul1eb8ef22005-04-07 07:30:20 +00001582 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001583 struct ospf_lsa *lsa;
1584
paul1eb8ef22005-04-07 07:30:20 +00001585 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1586 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001587
1588 list_delete (lsas);
1589}
1590
1591/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001592static void
paul718e3742002-12-13 20:15:29 +00001593ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1594 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1595{
1596 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001597 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001598 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001599 struct ospf_lsa *lsa = NULL;
1600 /* unsigned long ls_req_found = 0; */
1601
1602 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1603
1604 /* Increment statistics. */
1605 oi->ls_upd_in++;
1606
1607 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001608 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001609 if (nbr == NULL)
1610 {
1611 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1612 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1613 return;
1614 }
1615
1616 /* Check neighbor state. */
1617 if (nbr->state < NSM_Exchange)
1618 {
ajs3aa8d5f2004-12-11 18:00:06 +00001619 zlog_warn ("Link State Update: "
1620 "Neighbor[%s] state %s is less than Exchange",
1621 inet_ntoa (ospfh->router_id),
1622 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001623 return;
1624 }
1625
1626 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1627 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1628 * of section 13.
1629 */
1630 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1631
1632#ifdef HAVE_OPAQUE_LSA
1633 /*
paul718e3742002-12-13 20:15:29 +00001634 * If self-originated Opaque-LSAs that have flooded before restart
1635 * are contained in the received LSUpd message, corresponding LSReq
1636 * messages to be sent may have to be modified.
1637 * To eliminate possible race conditions such that flushing and normal
1638 * updating for the same LSA would take place alternately, this trick
1639 * must be done before entering to the loop below.
1640 */
paul69310a62005-05-11 18:09:59 +00001641 /* XXX: Why is this Opaque specific? Either our core code is deficient
1642 * and this should be fixed generally, or Opaque is inventing strawman
1643 * problems */
paul718e3742002-12-13 20:15:29 +00001644 ospf_opaque_adjust_lsreq (nbr, lsas);
1645#endif /* HAVE_OPAQUE_LSA */
1646
1647#define DISCARD_LSA(L,N) {\
1648 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001649 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 +00001650 ospf_lsa_discard (L); \
1651 continue; }
1652
1653 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001654 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001655 {
1656 struct ospf_lsa *ls_ret, *current;
1657 int ret = 1;
1658
paul718e3742002-12-13 20:15:29 +00001659 if (IS_DEBUG_OSPF_NSSA)
1660 {
1661 char buf1[INET_ADDRSTRLEN];
1662 char buf2[INET_ADDRSTRLEN];
1663 char buf3[INET_ADDRSTRLEN];
1664
ajs2a42e282004-12-08 18:43:03 +00001665 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001666 lsa->data->type,
1667 inet_ntop (AF_INET, &ospfh->router_id,
1668 buf1, INET_ADDRSTRLEN),
1669 inet_ntop (AF_INET, &lsa->data->id,
1670 buf2, INET_ADDRSTRLEN),
1671 inet_ntop (AF_INET, &lsa->data->adv_router,
1672 buf3, INET_ADDRSTRLEN));
1673 }
paul718e3742002-12-13 20:15:29 +00001674
1675 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1676
1677 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1678
1679 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1680
1681 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1682
1683 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1684
1685 /* Do take in Type-7's if we are an NSSA */
1686
1687 /* If we are also an ABR, later translate them to a Type-5 packet */
1688
1689 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1690 translate them to a separate Type-5 packet. */
1691
1692 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1693 /* Reject from STUB or NSSA */
1694 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1695 {
1696 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001697 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001698 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001699 }
1700
paul718e3742002-12-13 20:15:29 +00001701 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1702 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1703 {
1704 DISCARD_LSA (lsa,2);
1705 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001706 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001707 }
paul718e3742002-12-13 20:15:29 +00001708
1709 /* Find the LSA in the current database. */
1710
1711 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1712
1713 /* If the LSA's LS age is equal to MaxAge, and there is currently
1714 no instance of the LSA in the router's link state database,
1715 and none of router's neighbors are in states Exchange or Loading,
1716 then take the following actions. */
1717
1718 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001719 (ospf_nbr_count (oi, NSM_Exchange) +
1720 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001721 {
1722 /* Response Link State Acknowledgment. */
1723 ospf_ls_ack_send (nbr, lsa);
1724
1725 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001726 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1727 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001728 DISCARD_LSA (lsa, 3);
1729 }
1730
1731#ifdef HAVE_OPAQUE_LSA
1732 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001733 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001734 {
1735 /*
1736 * Even if initial flushing seems to be completed, there might
1737 * be a case that self-originated LSA with MaxAge still remain
1738 * in the routing domain.
1739 * Just send an LSAck message to cease retransmission.
1740 */
1741 if (IS_LSA_MAXAGE (lsa))
1742 {
1743 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1744 ospf_ls_ack_send (nbr, lsa);
1745 ospf_lsa_discard (lsa);
1746
1747 if (current != NULL && ! IS_LSA_MAXAGE (current))
1748 ospf_opaque_lsa_refresh_schedule (current);
1749 continue;
1750 }
1751
1752 /*
1753 * If an instance of self-originated Opaque-LSA is not found
1754 * in the LSDB, there are some possible cases here.
1755 *
1756 * 1) This node lost opaque-capability after restart.
1757 * 2) Else, a part of opaque-type is no more supported.
1758 * 3) Else, a part of opaque-id is no more supported.
1759 *
1760 * Anyway, it is still this node's responsibility to flush it.
1761 * Otherwise, the LSA instance remains in the routing domain
1762 * until its age reaches to MaxAge.
1763 */
paul69310a62005-05-11 18:09:59 +00001764 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001765 if (current == NULL)
1766 {
1767 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001768 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1769 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001770
1771 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001772
1773 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1774 ospf_ls_ack_send (nbr, lsa);
1775
paul718e3742002-12-13 20:15:29 +00001776 continue;
1777 }
1778 }
1779#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001780
hassocb05eb22004-02-11 21:10:19 +00001781 /* It might be happen that received LSA is self-originated network LSA, but
1782 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1783 * Link State ID is one of the router's own IP interface addresses but whose
1784 * Advertising Router is not equal to the router's own Router ID
1785 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1786 */
1787
1788 if(lsa->data->type == OSPF_NETWORK_LSA)
1789 {
paul1eb8ef22005-04-07 07:30:20 +00001790 struct listnode *oinode, *oinnode;
1791 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001792 int Flag = 0;
1793
paul1eb8ef22005-04-07 07:30:20 +00001794 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001795 {
hassocb05eb22004-02-11 21:10:19 +00001796 if(out_if == NULL)
1797 break;
1798
1799 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1800 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1801 {
1802 if(out_if->network_lsa_self)
1803 {
1804 ospf_lsa_flush_area(lsa,out_if->area);
1805 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001806 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001807 lsa, (int) lsa->data->type);
1808 ospf_lsa_discard (lsa);
1809 Flag = 1;
1810 }
1811 break;
1812 }
1813 }
1814 if(Flag)
1815 continue;
1816 }
paul718e3742002-12-13 20:15:29 +00001817
1818 /* (5) Find the instance of this LSA that is currently contained
1819 in the router's link state database. If there is no
1820 database copy, or the received LSA is more recent than
1821 the database copy the following steps must be performed. */
1822
1823 if (current == NULL ||
1824 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1825 {
1826 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001827 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001828 DISCARD_LSA (lsa, 4);
1829 continue;
1830 }
1831
1832 /* (6) Else, If there is an instance of the LSA on the sending
1833 neighbor's Link state request list, an error has occurred in
1834 the Database Exchange process. In this case, restart the
1835 Database Exchange process by generating the neighbor event
1836 BadLSReq for the sending neighbor and stop processing the
1837 Link State Update packet. */
1838
1839 if (ospf_ls_request_lookup (nbr, lsa))
1840 {
1841 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001842 zlog_warn("LSA[%s] instance exists on Link state request list",
1843 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001844
1845 /* Clean list of LSAs. */
1846 ospf_upd_list_clean (lsas);
1847 /* this lsa is not on lsas list already. */
1848 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001849 return;
1850 }
1851
1852 /* If the received LSA is the same instance as the database copy
1853 (i.e., neither one is more recent) the following two steps
1854 should be performed: */
1855
1856 if (ret == 0)
1857 {
1858 /* If the LSA is listed in the Link state retransmission list
1859 for the receiving adjacency, the router itself is expecting
1860 an acknowledgment for this LSA. The router should treat the
1861 received LSA as an acknowledgment by removing the LSA from
1862 the Link state retransmission list. This is termed an
1863 "implied acknowledgment". */
1864
1865 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1866
1867 if (ls_ret != NULL)
1868 {
1869 ospf_ls_retransmit_delete (nbr, ls_ret);
1870
1871 /* Delayed acknowledgment sent if advertisement received
1872 from Designated Router, otherwise do nothing. */
1873 if (oi->state == ISM_Backup)
1874 if (NBR_IS_DR (nbr))
1875 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1876
1877 DISCARD_LSA (lsa, 5);
1878 }
1879 else
1880 /* Acknowledge the receipt of the LSA by sending a
1881 Link State Acknowledgment packet back out the receiving
1882 interface. */
1883 {
1884 ospf_ls_ack_send (nbr, lsa);
1885 DISCARD_LSA (lsa, 6);
1886 }
1887 }
1888
1889 /* The database copy is more recent. If the database copy
1890 has LS age equal to MaxAge and LS sequence number equal to
1891 MaxSequenceNumber, simply discard the received LSA without
1892 acknowledging it. (In this case, the LSA's LS sequence number is
1893 wrapping, and the MaxSequenceNumber LSA must be completely
1894 flushed before any new LSA instance can be introduced). */
1895
1896 else if (ret > 0) /* Database copy is more recent */
1897 {
1898 if (IS_LSA_MAXAGE (current) &&
1899 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1900 {
1901 DISCARD_LSA (lsa, 7);
1902 }
1903 /* Otherwise, as long as the database copy has not been sent in a
1904 Link State Update within the last MinLSArrival seconds, send the
1905 database copy back to the sending neighbor, encapsulated within
1906 a Link State Update Packet. The Link State Update Packet should
1907 be sent directly to the neighbor. In so doing, do not put the
1908 database copy of the LSA on the neighbor's link state
1909 retransmission list, and do not acknowledge the received (less
1910 recent) LSA instance. */
1911 else
1912 {
1913 struct timeval now;
1914
1915 gettimeofday (&now, NULL);
1916
1917 if (tv_cmp (tv_sub (now, current->tv_orig),
1918 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1919 /* Trap NSSA type later.*/
1920 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1921 DISCARD_LSA (lsa, 8);
1922 }
1923 }
1924 }
1925
paul718e3742002-12-13 20:15:29 +00001926 assert (listcount (lsas) == 0);
1927 list_delete (lsas);
1928}
1929
1930/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001931static void
paul718e3742002-12-13 20:15:29 +00001932ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1933 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1934{
1935 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001936
paul718e3742002-12-13 20:15:29 +00001937 /* increment statistics. */
1938 oi->ls_ack_in++;
1939
pauld3f0d622004-05-05 15:27:15 +00001940 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001941 if (nbr == NULL)
1942 {
1943 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1944 inet_ntoa (ospfh->router_id));
1945 return;
1946 }
1947
1948 if (nbr->state < NSM_Exchange)
1949 {
ajs3aa8d5f2004-12-11 18:00:06 +00001950 zlog_warn ("Link State Acknowledgment: "
1951 "Neighbor[%s] state %s is less than Exchange",
1952 inet_ntoa (ospfh->router_id),
1953 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001954 return;
1955 }
paul69310a62005-05-11 18:09:59 +00001956
paul718e3742002-12-13 20:15:29 +00001957 while (size >= OSPF_LSA_HEADER_SIZE)
1958 {
1959 struct ospf_lsa *lsa, *lsr;
1960
1961 lsa = ospf_lsa_new ();
1962 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1963
1964 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1965 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00001966 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001967
1968 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1969 {
1970 lsa->data = NULL;
1971 ospf_lsa_discard (lsa);
1972 continue;
1973 }
1974
1975 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1976
1977 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1978 {
1979#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001980 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00001981 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00001982#endif /* HAVE_OPAQUE_LSA */
1983
1984 ospf_ls_retransmit_delete (nbr, lsr);
1985 }
1986
1987 lsa->data = NULL;
1988 ospf_lsa_discard (lsa);
1989 }
1990
paul718e3742002-12-13 20:15:29 +00001991 return;
paul718e3742002-12-13 20:15:29 +00001992}
1993
ajs038163f2005-02-17 19:55:59 +00001994static struct stream *
ajs5c333492005-02-23 15:43:01 +00001995ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00001996{
1997 int ret;
ajs5c333492005-02-23 15:43:01 +00001998 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00001999 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002000 unsigned int ifindex = 0;
2001 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002002 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002003 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002004 struct msghdr msgh;
2005
paul68defd62004-09-27 07:27:13 +00002006 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002007 msgh.msg_iov = &iov;
2008 msgh.msg_iovlen = 1;
2009 msgh.msg_control = (caddr_t) buff;
2010 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002011
ajs5c333492005-02-23 15:43:01 +00002012 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2013 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002014 {
ajs5c333492005-02-23 15:43:01 +00002015 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2016 return NULL;
2017 }
paul69310a62005-05-11 18:09:59 +00002018 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002019 {
2020 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2021 "(ip header size is %u)",
2022 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002023 return NULL;
2024 }
paul18b12c32004-10-05 14:38:29 +00002025
ajs5c333492005-02-23 15:43:01 +00002026 /* Note that there should not be alignment problems with this assignment
2027 because this is at the beginning of the stream data buffer. */
2028 iph = (struct ip *) STREAM_DATA(ibuf);
2029 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002030
ajs5c333492005-02-23 15:43:01 +00002031 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002032
paul239aecc2003-12-08 10:34:54 +00002033#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002034 /*
2035 * Kernel network code touches incoming IP header parameters,
2036 * before protocol specific processing.
2037 *
2038 * 1) Convert byteorder to host representation.
2039 * --> ip_len, ip_id, ip_off
2040 *
2041 * 2) Adjust ip_len to strip IP header size!
2042 * --> If user process receives entire IP packet via RAW
2043 * socket, it must consider adding IP header size to
2044 * the "ip_len" field of "ip" structure.
2045 *
2046 * For more details, see <netinet/ip_input.c>.
2047 */
ajs5c333492005-02-23 15:43:01 +00002048 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002049#endif
2050
paul863082d2004-08-19 04:43:43 +00002051 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002052
2053 *ifp = if_lookup_by_index (ifindex);
2054
2055 if (ret != ip_len)
2056 {
ajs5c333492005-02-23 15:43:01 +00002057 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2058 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002059 return NULL;
2060 }
2061
2062 return ibuf;
2063}
2064
paul4dadc292005-05-06 21:37:42 +00002065static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002066ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002067 struct ip *iph, struct ospf_header *ospfh)
2068{
2069 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002070 struct ospf_vl_data *vl_data;
2071 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002072 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002073
2074 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2075 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002076 return NULL;
paul718e3742002-12-13 20:15:29 +00002077
pauld3f0d622004-05-05 15:27:15 +00002078 /* look for local OSPF interface matching the destination
2079 * to determine Area ID. We presume therefore the destination address
2080 * is unique, or at least (for "unnumbered" links), not used in other
2081 * areas
2082 */
2083 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2084 iph->ip_dst)) == NULL)
2085 return NULL;
paul718e3742002-12-13 20:15:29 +00002086
paul1eb8ef22005-04-07 07:30:20 +00002087 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002088 {
paul020709f2003-04-04 02:44:16 +00002089 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002090 if (!vl_area)
2091 continue;
2092
2093 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2094 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2095 {
2096 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002097 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002098 IF_NAME (vl_data->vl_oi));
2099 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2100 {
2101 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002102 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002103 return NULL;
2104 }
2105
2106 return vl_data->vl_oi;
2107 }
2108 }
2109
2110 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002111 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002112
pauld3f0d622004-05-05 15:27:15 +00002113 return NULL;
paul718e3742002-12-13 20:15:29 +00002114}
2115
paul4dadc292005-05-06 21:37:42 +00002116static inline int
paul718e3742002-12-13 20:15:29 +00002117ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2118{
2119 /* Check match the Area ID of the receiving interface. */
2120 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2121 return 1;
2122
2123 return 0;
2124}
2125
2126/* Unbound socket will accept any Raw IP packets if proto is matched.
2127 To prevent it, compare src IP address and i/f address with masking
2128 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002129static int
paul718e3742002-12-13 20:15:29 +00002130ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2131{
2132 struct in_addr mask, me, him;
2133
2134 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2135 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2136 return 1;
2137
2138 masklen2ip (oi->address->prefixlen, &mask);
2139
2140 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2141 him.s_addr = ip_src.s_addr & mask.s_addr;
2142
2143 if (IPV4_ADDR_SAME (&me, &him))
2144 return 1;
2145
2146 return 0;
2147}
2148
paul4dadc292005-05-06 21:37:42 +00002149static int
paul718e3742002-12-13 20:15:29 +00002150ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2151 struct ospf_header *ospfh)
2152{
2153 int ret = 0;
2154 struct crypt_key *ck;
2155
2156 switch (ntohs (ospfh->auth_type))
2157 {
2158 case OSPF_AUTH_NULL:
2159 ret = 1;
2160 break;
2161 case OSPF_AUTH_SIMPLE:
2162 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2163 ret = 1;
2164 else
2165 ret = 0;
2166 break;
2167 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002168 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002169 {
2170 ret = 0;
2171 break;
2172 }
2173
2174 /* This is very basic, the digest processing is elsewhere */
2175 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2176 ospfh->u.crypt.key_id == ck->key_id &&
2177 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2178 ret = 1;
2179 else
2180 ret = 0;
2181 break;
2182 default:
2183 ret = 0;
2184 break;
2185 }
2186
2187 return ret;
2188}
2189
paul4dadc292005-05-06 21:37:42 +00002190static int
paul718e3742002-12-13 20:15:29 +00002191ospf_check_sum (struct ospf_header *ospfh)
2192{
2193 u_int32_t ret;
2194 u_int16_t sum;
2195 int in_cksum (void *ptr, int nbytes);
2196
2197 /* clear auth_data for checksum. */
2198 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2199
2200 /* keep checksum and clear. */
2201 sum = ospfh->checksum;
2202 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2203
2204 /* calculate checksum. */
2205 ret = in_cksum (ospfh, ntohs (ospfh->length));
2206
2207 if (ret != sum)
2208 {
2209 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2210 ret, sum);
2211 return 0;
2212 }
2213
2214 return 1;
2215}
2216
2217/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002218static int
paul718e3742002-12-13 20:15:29 +00002219ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2220 struct ip *iph, struct ospf_header *ospfh)
2221{
2222 /* check version. */
2223 if (ospfh->version != OSPF_VERSION)
2224 {
2225 zlog_warn ("interface %s: ospf_read version number mismatch.",
2226 IF_NAME (oi));
2227 return -1;
2228 }
2229
2230 /* Check Area ID. */
2231 if (!ospf_check_area_id (oi, ospfh))
2232 {
2233 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2234 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2235 return -1;
2236 }
2237
2238 /* Check network mask, Silently discarded. */
2239 if (! ospf_check_network_mask (oi, iph->ip_src))
2240 {
2241 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2242 IF_NAME (oi), inet_ntoa (iph->ip_src));
2243 return -1;
2244 }
2245
2246 /* Check authentication. */
2247 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2248 {
2249 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2250 IF_NAME (oi));
2251 return -1;
2252 }
2253
2254 if (! ospf_check_auth (oi, ibuf, ospfh))
2255 {
2256 zlog_warn ("interface %s: ospf_read authentication failed.",
2257 IF_NAME (oi));
2258 return -1;
2259 }
2260
2261 /* if check sum is invalid, packet is discarded. */
2262 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2263 {
2264 if (! ospf_check_sum (ospfh))
2265 {
2266 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2267 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2268 return -1;
2269 }
2270 }
2271 else
2272 {
2273 if (ospfh->checksum != 0)
2274 return -1;
2275 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2276 {
2277 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2278 IF_NAME (oi));
2279 return -1;
2280 }
2281 }
2282
2283 return 0;
2284}
2285
2286/* Starting point of packet process function. */
2287int
2288ospf_read (struct thread *thread)
2289{
2290 int ret;
2291 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002292 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002293 struct ospf_interface *oi;
2294 struct ip *iph;
2295 struct ospf_header *ospfh;
2296 u_int16_t length;
2297 struct interface *ifp;
2298
2299 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002300 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002301
2302 /* prepare for next packet. */
2303 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002304
2305 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002306 stream_reset(ospf->ibuf);
2307 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002308 return -1;
2309
ajs5c333492005-02-23 15:43:01 +00002310 /* Note that there should not be alignment problems with this assignment
2311 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002312 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002313 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002314
paulac191232004-10-22 12:05:17 +00002315 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002316 /* Handle cases where the platform does not support retrieving the ifindex,
2317 and also platforms (such as Solaris 8) that claim to support ifindex
2318 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002319 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002320
pauld3f0d622004-05-05 15:27:15 +00002321 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002322 return 0;
paul718e3742002-12-13 20:15:29 +00002323
2324 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002325 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002326 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002327
paul718e3742002-12-13 20:15:29 +00002328 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002329 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002330 {
pauld3241812003-09-29 12:42:39 +00002331 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2332 {
ajs2a42e282004-12-08 18:43:03 +00002333 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002334 inet_ntoa (iph->ip_src));
2335 }
paul718e3742002-12-13 20:15:29 +00002336 return 0;
2337 }
2338
2339 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002340 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002341
2342 /* Get ospf packet header. */
2343 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2344
2345 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002346 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002347
2348 /* if no local ospf_interface,
2349 * or header area is backbone but ospf_interface is not
2350 * check for VLINK interface
2351 */
2352 if ( (oi == NULL) ||
2353 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2354 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2355 )
2356 {
2357 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2358 {
2359 zlog_warn ("Packet from [%s] received on link %s"
2360 " but no ospf_interface",
2361 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002362 return 0;
2363 }
2364 }
2365
2366 /* else it must be a local ospf interface, check it was received on
2367 * correct link
2368 */
2369 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002370 {
2371 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002372 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002373 return 0;
2374 }
ajs847947f2005-02-02 18:38:48 +00002375 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002376 {
ajsba6454e2005-02-08 15:37:30 +00002377 char buf[2][INET_ADDRSTRLEN];
2378 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002379 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002380 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2381 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2382 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002383 /* Fix multicast memberships? */
2384 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2385 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2386 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2387 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2388 if (oi->multicast_memberships)
2389 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002390 return 0;
2391 }
paul718e3742002-12-13 20:15:29 +00002392
2393 /*
2394 * If the received packet is destined for AllDRouters, the packet
2395 * should be accepted only if the received ospf interface state is
2396 * either DR or Backup -- endo.
2397 */
2398 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2399 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2400 {
ajsba6454e2005-02-08 15:37:30 +00002401 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002402 inet_ntoa (iph->ip_src), IF_NAME (oi),
2403 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002404 /* Try to fix multicast membership. */
2405 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2406 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002407 return 0;
2408 }
2409
2410 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002411 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2412 {
paul718e3742002-12-13 20:15:29 +00002413 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002414 {
ajs2a42e282004-12-08 18:43:03 +00002415 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002416 ospf_packet_dump (ibuf);
2417 }
paul718e3742002-12-13 20:15:29 +00002418
ajs2a42e282004-12-08 18:43:03 +00002419 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002420 ospf_packet_type_str[ospfh->type],
2421 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002422 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2423 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002424
2425 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002426 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002427 }
paul718e3742002-12-13 20:15:29 +00002428
2429 /* Some header verification. */
2430 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2431 if (ret < 0)
2432 {
pauld3241812003-09-29 12:42:39 +00002433 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2434 {
ajs2a42e282004-12-08 18:43:03 +00002435 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002436 "dropping.",
2437 ospf_packet_type_str[ospfh->type],
2438 inet_ntoa (iph->ip_src));
2439 }
paul718e3742002-12-13 20:15:29 +00002440 return ret;
2441 }
2442
paul9985f832005-02-09 15:51:56 +00002443 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002444
2445 /* Adjust size to message length. */
2446 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2447
2448 /* Read rest of the packet and call each sort of packet routine. */
2449 switch (ospfh->type)
2450 {
2451 case OSPF_MSG_HELLO:
2452 ospf_hello (iph, ospfh, ibuf, oi, length);
2453 break;
2454 case OSPF_MSG_DB_DESC:
2455 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2456 break;
2457 case OSPF_MSG_LS_REQ:
2458 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2459 break;
2460 case OSPF_MSG_LS_UPD:
2461 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2462 break;
2463 case OSPF_MSG_LS_ACK:
2464 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2465 break;
2466 default:
2467 zlog (NULL, LOG_WARNING,
2468 "interface %s: OSPF packet header type %d is illegal",
2469 IF_NAME (oi), ospfh->type);
2470 break;
2471 }
2472
paul718e3742002-12-13 20:15:29 +00002473 return 0;
2474}
2475
2476/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002477static void
paul718e3742002-12-13 20:15:29 +00002478ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2479{
2480 struct ospf_header *ospfh;
2481
2482 ospfh = (struct ospf_header *) STREAM_DATA (s);
2483
2484 ospfh->version = (u_char) OSPF_VERSION;
2485 ospfh->type = (u_char) type;
2486
paul68980082003-03-25 05:07:42 +00002487 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002488
2489 ospfh->checksum = 0;
2490 ospfh->area_id = oi->area->area_id;
2491 ospfh->auth_type = htons (ospf_auth_type (oi));
2492
2493 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2494
paul9985f832005-02-09 15:51:56 +00002495 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002496}
2497
2498/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002499static int
paul718e3742002-12-13 20:15:29 +00002500ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2501{
2502 struct crypt_key *ck;
2503
2504 switch (ospf_auth_type (oi))
2505 {
2506 case OSPF_AUTH_NULL:
2507 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2508 break;
2509 case OSPF_AUTH_SIMPLE:
2510 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2511 OSPF_AUTH_SIMPLE_SIZE);
2512 break;
2513 case OSPF_AUTH_CRYPTOGRAPHIC:
2514 /* If key is not set, then set 0. */
2515 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2516 {
2517 ospfh->u.crypt.zero = 0;
2518 ospfh->u.crypt.key_id = 0;
2519 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2520 }
2521 else
2522 {
paul1eb8ef22005-04-07 07:30:20 +00002523 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002524 ospfh->u.crypt.zero = 0;
2525 ospfh->u.crypt.key_id = ck->key_id;
2526 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2527 }
2528 /* note: the seq is done in ospf_make_md5_digest() */
2529 break;
2530 default:
2531 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2532 break;
2533 }
2534
2535 return 0;
2536}
2537
2538/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002539static void
paul718e3742002-12-13 20:15:29 +00002540ospf_fill_header (struct ospf_interface *oi,
2541 struct stream *s, u_int16_t length)
2542{
2543 struct ospf_header *ospfh;
2544
2545 ospfh = (struct ospf_header *) STREAM_DATA (s);
2546
2547 /* Fill length. */
2548 ospfh->length = htons (length);
2549
2550 /* Calculate checksum. */
2551 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2552 ospfh->checksum = in_cksum (ospfh, length);
2553 else
2554 ospfh->checksum = 0;
2555
2556 /* Add Authentication Data. */
2557 ospf_make_auth (oi, ospfh);
2558}
2559
paul4dadc292005-05-06 21:37:42 +00002560static int
paul718e3742002-12-13 20:15:29 +00002561ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2562{
2563 struct ospf_neighbor *nbr;
2564 struct route_node *rn;
2565 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2566 struct in_addr mask;
2567 unsigned long p;
2568 int flag = 0;
2569
2570 /* Set netmask of interface. */
2571 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2572 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2573 masklen2ip (oi->address->prefixlen, &mask);
2574 else
2575 memset ((char *) &mask, 0, sizeof (struct in_addr));
2576 stream_put_ipv4 (s, mask.s_addr);
2577
2578 /* Set Hello Interval. */
2579 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2580
2581 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002582 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002583 OPTIONS(oi), IF_NAME (oi));
2584
2585 /* Set Options. */
2586 stream_putc (s, OPTIONS (oi));
2587
2588 /* Set Router Priority. */
2589 stream_putc (s, PRIORITY (oi));
2590
2591 /* Set Router Dead Interval. */
2592 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2593
2594 /* Set Designated Router. */
2595 stream_put_ipv4 (s, DR (oi).s_addr);
2596
paul9985f832005-02-09 15:51:56 +00002597 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002598
2599 /* Set Backup Designated Router. */
2600 stream_put_ipv4 (s, BDR (oi).s_addr);
2601
2602 /* Add neighbor seen. */
2603 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002604 if ((nbr = rn->info))
2605 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2606 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2607 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2608 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002609 {
2610 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002611 if (nbr->d_router.s_addr != 0
2612 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2613 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2614 flag = 1;
paul718e3742002-12-13 20:15:29 +00002615
2616 stream_put_ipv4 (s, nbr->router_id.s_addr);
2617 length += 4;
2618 }
2619
2620 /* Let neighbor generate BackupSeen. */
2621 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002622 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002623
2624 return length;
2625}
2626
paul4dadc292005-05-06 21:37:42 +00002627static int
paul718e3742002-12-13 20:15:29 +00002628ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2629 struct stream *s)
2630{
2631 struct ospf_lsa *lsa;
2632 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2633 u_char options;
2634 unsigned long pp;
2635 int i;
2636 struct ospf_lsdb *lsdb;
2637
2638 /* Set Interface MTU. */
2639 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2640 stream_putw (s, 0);
2641 else
2642 stream_putw (s, oi->ifp->mtu);
2643
2644 /* Set Options. */
2645 options = OPTIONS (oi);
2646#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002647 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002648 {
2649 if (IS_SET_DD_I (nbr->dd_flags)
2650 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2651 /*
2652 * Set O-bit in the outgoing DD packet for capablity negotiation,
2653 * if one of following case is applicable.
2654 *
2655 * 1) WaitTimer expiration event triggered the neighbor state to
2656 * change to Exstart, but no (valid) DD packet has received
2657 * from the neighbor yet.
2658 *
2659 * 2) At least one DD packet with O-bit on has received from the
2660 * neighbor.
2661 */
2662 SET_FLAG (options, OSPF_OPTION_O);
2663 }
2664#endif /* HAVE_OPAQUE_LSA */
2665 stream_putc (s, options);
2666
2667 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002668 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002669 stream_putc (s, nbr->dd_flags);
2670
2671 /* Set DD Sequence Number. */
2672 stream_putl (s, nbr->dd_seqnum);
2673
2674 if (ospf_db_summary_isempty (nbr))
2675 {
2676 if (nbr->state >= NSM_Exchange)
2677 {
2678 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2679 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002680 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002681 }
2682 return length;
2683 }
2684
2685 /* Describe LSA Header from Database Summary List. */
2686 lsdb = &nbr->db_sum;
2687
2688 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2689 {
2690 struct route_table *table = lsdb->type[i].db;
2691 struct route_node *rn;
2692
2693 for (rn = route_top (table); rn; rn = route_next (rn))
2694 if ((lsa = rn->info) != NULL)
2695 {
2696#ifdef HAVE_OPAQUE_LSA
2697 if (IS_OPAQUE_LSA (lsa->data->type)
2698 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2699 {
2700 /* Suppress advertising opaque-informations. */
2701 /* Remove LSA from DB summary list. */
2702 ospf_lsdb_delete (lsdb, lsa);
2703 continue;
2704 }
2705#endif /* HAVE_OPAQUE_LSA */
2706
2707 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2708 {
2709 struct lsa_header *lsah;
2710 u_int16_t ls_age;
2711
2712 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002713 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002714 break;
2715
2716 /* Keep pointer to LS age. */
2717 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002718 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002719
2720 /* Proceed stream pointer. */
2721 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2722 length += OSPF_LSA_HEADER_SIZE;
2723
2724 /* Set LS age. */
2725 ls_age = LS_AGE (lsa);
2726 lsah->ls_age = htons (ls_age);
2727
2728 }
2729
2730 /* Remove LSA from DB summary list. */
2731 ospf_lsdb_delete (lsdb, lsa);
2732 }
2733 }
2734
2735 return length;
2736}
2737
paul4dadc292005-05-06 21:37:42 +00002738static int
paul718e3742002-12-13 20:15:29 +00002739ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2740 unsigned long delta, struct ospf_neighbor *nbr,
2741 struct ospf_lsa *lsa)
2742{
2743 struct ospf_interface *oi;
2744
2745 oi = nbr->oi;
2746
2747 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002748 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002749 return 0;
2750
2751 stream_putl (s, lsa->data->type);
2752 stream_put_ipv4 (s, lsa->data->id.s_addr);
2753 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2754
2755 ospf_lsa_unlock (nbr->ls_req_last);
2756 nbr->ls_req_last = ospf_lsa_lock (lsa);
2757
2758 *length += 12;
2759 return 1;
2760}
2761
paul4dadc292005-05-06 21:37:42 +00002762static int
paul718e3742002-12-13 20:15:29 +00002763ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2764{
2765 struct ospf_lsa *lsa;
2766 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002767 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002768 struct route_table *table;
2769 struct route_node *rn;
2770 int i;
2771 struct ospf_lsdb *lsdb;
2772
2773 lsdb = &nbr->ls_req;
2774
2775 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2776 {
2777 table = lsdb->type[i].db;
2778 for (rn = route_top (table); rn; rn = route_next (rn))
2779 if ((lsa = (rn->info)) != NULL)
2780 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2781 {
2782 route_unlock_node (rn);
2783 break;
2784 }
2785 }
2786 return length;
2787}
2788
paul4dadc292005-05-06 21:37:42 +00002789static int
paul718e3742002-12-13 20:15:29 +00002790ls_age_increment (struct ospf_lsa *lsa, int delay)
2791{
2792 int age;
2793
2794 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2795
2796 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2797}
2798
paul4dadc292005-05-06 21:37:42 +00002799static int
hasso52dc7ee2004-09-23 19:18:23 +00002800ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002801{
2802 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002803 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002804 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002805 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002806 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002807 unsigned long pp;
2808 int count = 0;
2809
2810 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002811 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002812
paul9985f832005-02-09 15:51:56 +00002813 pp = stream_get_endp (s);
2814 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002815
gdt86f1fd92005-01-10 14:20:43 +00002816 /* Calculate amount of packet usable for data. */
2817 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2818
paul718e3742002-12-13 20:15:29 +00002819 while ((node = listhead (update)) != NULL)
2820 {
2821 struct lsa_header *lsah;
2822 u_int16_t ls_age;
2823
2824 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002825 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002826
paul1eb8ef22005-04-07 07:30:20 +00002827 lsa = listgetdata (node);
2828
paul718e3742002-12-13 20:15:29 +00002829 assert (lsa->data);
2830
paul68b73392004-09-12 14:21:37 +00002831 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002832 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002833 break;
2834
paul718e3742002-12-13 20:15:29 +00002835 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002836 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002837
2838 /* Put LSA to Link State Request. */
2839 stream_put (s, lsa->data, ntohs (lsa->data->length));
2840
2841 /* Set LS age. */
2842 /* each hop must increment an lsa_age by transmit_delay
2843 of OSPF interface */
2844 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2845 lsah->ls_age = htons (ls_age);
2846
2847 length += ntohs (lsa->data->length);
2848 count++;
2849
2850 list_delete_node (update, node);
2851 ospf_lsa_unlock (lsa);
2852 }
2853
2854 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002855 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002856
2857 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002858 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002859 return length;
2860}
2861
paul4dadc292005-05-06 21:37:42 +00002862static int
hasso52dc7ee2004-09-23 19:18:23 +00002863ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002864{
hasso52dc7ee2004-09-23 19:18:23 +00002865 struct list *rm_list;
2866 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002867 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002868 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002869 struct ospf_lsa *lsa;
2870
2871 rm_list = list_new ();
2872
paul1eb8ef22005-04-07 07:30:20 +00002873 for (ALL_LIST_ELEMENTS_RO (ack, node, lsa))
paul718e3742002-12-13 20:15:29 +00002874 {
paul1eb8ef22005-04-07 07:30:20 +00002875 lsa = listgetdata (node);
paul718e3742002-12-13 20:15:29 +00002876 assert (lsa);
2877
gdt86f1fd92005-01-10 14:20:43 +00002878 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002879 break;
2880
2881 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2882 length += OSPF_LSA_HEADER_SIZE;
2883
2884 listnode_add (rm_list, lsa);
2885 }
2886
2887 /* Remove LSA from LS-Ack list. */
paul1eb8ef22005-04-07 07:30:20 +00002888 /* XXX: this loop should be removed and the list move done in previous
2889 * loop
2890 */
2891 for (ALL_LIST_ELEMENTS_RO (rm_list, node, lsa))
paul718e3742002-12-13 20:15:29 +00002892 {
paul718e3742002-12-13 20:15:29 +00002893 listnode_delete (ack, lsa);
2894 ospf_lsa_unlock (lsa);
2895 }
2896
2897 list_delete (rm_list);
2898
2899 return length;
2900}
2901
2902void
2903ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2904{
2905 struct ospf_packet *op;
2906 u_int16_t length = OSPF_HEADER_SIZE;
2907
2908 op = ospf_packet_new (oi->ifp->mtu);
2909
2910 /* Prepare OSPF common header. */
2911 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2912
2913 /* Prepare OSPF Hello body. */
2914 length += ospf_make_hello (oi, op->s);
2915
2916 /* Fill OSPF header. */
2917 ospf_fill_header (oi, op->s, length);
2918
2919 /* Set packet length. */
2920 op->length = length;
2921
2922 op->dst.s_addr = addr->s_addr;
2923
2924 /* Add packet to the interface output queue. */
2925 ospf_packet_add (oi, op);
2926
2927 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002928 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002929}
2930
paul4dadc292005-05-06 21:37:42 +00002931static void
paul718e3742002-12-13 20:15:29 +00002932ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2933{
2934 struct ospf_interface *oi;
2935
2936 oi = nbr_nbma->oi;
2937 assert(oi);
2938
2939 /* If this is passive interface, do not send OSPF Hello. */
2940 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2941 return;
2942
2943 if (oi->type != OSPF_IFTYPE_NBMA)
2944 return;
2945
2946 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2947 return;
2948
2949 if (PRIORITY(oi) == 0)
2950 return;
2951
2952 if (nbr_nbma->priority == 0
2953 && oi->state != ISM_DR && oi->state != ISM_Backup)
2954 return;
2955
2956 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2957}
2958
2959int
2960ospf_poll_timer (struct thread *thread)
2961{
2962 struct ospf_nbr_nbma *nbr_nbma;
2963
2964 nbr_nbma = THREAD_ARG (thread);
2965 nbr_nbma->t_poll = NULL;
2966
2967 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002968 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002969 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2970
2971 ospf_poll_send (nbr_nbma);
2972
2973 if (nbr_nbma->v_poll > 0)
2974 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2975 nbr_nbma->v_poll);
2976
2977 return 0;
2978}
2979
2980
2981int
2982ospf_hello_reply_timer (struct thread *thread)
2983{
2984 struct ospf_neighbor *nbr;
2985
2986 nbr = THREAD_ARG (thread);
2987 nbr->t_hello_reply = NULL;
2988
2989 assert (nbr->oi);
2990
2991 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002992 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00002993 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2994
2995 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2996
2997 return 0;
2998}
2999
3000/* Send OSPF Hello. */
3001void
3002ospf_hello_send (struct ospf_interface *oi)
3003{
3004 struct ospf_packet *op;
3005 u_int16_t length = OSPF_HEADER_SIZE;
3006
3007 /* If this is passive interface, do not send OSPF Hello. */
3008 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3009 return;
3010
3011 op = ospf_packet_new (oi->ifp->mtu);
3012
3013 /* Prepare OSPF common header. */
3014 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3015
3016 /* Prepare OSPF Hello body. */
3017 length += ospf_make_hello (oi, op->s);
3018
3019 /* Fill OSPF header. */
3020 ospf_fill_header (oi, op->s, length);
3021
3022 /* Set packet length. */
3023 op->length = length;
3024
3025 if (oi->type == OSPF_IFTYPE_NBMA)
3026 {
3027 struct ospf_neighbor *nbr;
3028 struct route_node *rn;
3029
3030 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3031 if ((nbr = rn->info))
3032 if (nbr != oi->nbr_self)
3033 if (nbr->state != NSM_Down)
3034 {
3035 /* RFC 2328 Section 9.5.1
3036 If the router is not eligible to become Designated Router,
3037 it must periodically send Hello Packets to both the
3038 Designated Router and the Backup Designated Router (if they
3039 exist). */
3040 if (PRIORITY(oi) == 0 &&
3041 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3042 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3043 continue;
3044
3045 /* If the router is eligible to become Designated Router, it
3046 must periodically send Hello Packets to all neighbors that
3047 are also eligible. In addition, if the router is itself the
3048 Designated Router or Backup Designated Router, it must also
3049 send periodic Hello Packets to all other neighbors. */
3050
3051 if (nbr->priority == 0 && oi->state == ISM_DROther)
3052 continue;
3053 /* if oi->state == Waiting, send hello to all neighbors */
3054 {
3055 struct ospf_packet *op_dup;
3056
3057 op_dup = ospf_packet_dup(op);
3058 op_dup->dst = nbr->address.u.prefix4;
3059
3060 /* Add packet to the interface output queue. */
3061 ospf_packet_add (oi, op_dup);
3062
paul020709f2003-04-04 02:44:16 +00003063 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003064 }
3065
3066 }
3067 ospf_packet_free (op);
3068 }
3069 else
3070 {
3071 /* Decide destination address. */
3072 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3073 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3074 else
3075 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3076
3077 /* Add packet to the interface output queue. */
3078 ospf_packet_add (oi, op);
3079
3080 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003081 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003082 }
3083}
3084
3085/* Send OSPF Database Description. */
3086void
3087ospf_db_desc_send (struct ospf_neighbor *nbr)
3088{
3089 struct ospf_interface *oi;
3090 struct ospf_packet *op;
3091 u_int16_t length = OSPF_HEADER_SIZE;
3092
3093 oi = nbr->oi;
3094 op = ospf_packet_new (oi->ifp->mtu);
3095
3096 /* Prepare OSPF common header. */
3097 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3098
3099 /* Prepare OSPF Database Description body. */
3100 length += ospf_make_db_desc (oi, nbr, op->s);
3101
3102 /* Fill OSPF header. */
3103 ospf_fill_header (oi, op->s, length);
3104
3105 /* Set packet length. */
3106 op->length = length;
3107
3108 /* Decide destination address. */
3109 op->dst = nbr->address.u.prefix4;
3110
3111 /* Add packet to the interface output queue. */
3112 ospf_packet_add (oi, op);
3113
3114 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003115 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003116
3117 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3118 if (nbr->last_send)
3119 ospf_packet_free (nbr->last_send);
3120 nbr->last_send = ospf_packet_dup (op);
3121 gettimeofday (&nbr->last_send_ts, NULL);
3122}
3123
3124/* Re-send Database Description. */
3125void
3126ospf_db_desc_resend (struct ospf_neighbor *nbr)
3127{
3128 struct ospf_interface *oi;
3129
3130 oi = nbr->oi;
3131
3132 /* Add packet to the interface output queue. */
3133 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3134
3135 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003136 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003137}
3138
3139/* Send Link State Request. */
3140void
3141ospf_ls_req_send (struct ospf_neighbor *nbr)
3142{
3143 struct ospf_interface *oi;
3144 struct ospf_packet *op;
3145 u_int16_t length = OSPF_HEADER_SIZE;
3146
3147 oi = nbr->oi;
3148 op = ospf_packet_new (oi->ifp->mtu);
3149
3150 /* Prepare OSPF common header. */
3151 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3152
3153 /* Prepare OSPF Link State Request body. */
3154 length += ospf_make_ls_req (nbr, op->s);
3155 if (length == OSPF_HEADER_SIZE)
3156 {
3157 ospf_packet_free (op);
3158 return;
3159 }
3160
3161 /* Fill OSPF header. */
3162 ospf_fill_header (oi, op->s, length);
3163
3164 /* Set packet length. */
3165 op->length = length;
3166
3167 /* Decide destination address. */
3168 op->dst = nbr->address.u.prefix4;
3169
3170 /* Add packet to the interface output queue. */
3171 ospf_packet_add (oi, op);
3172
3173 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003174 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003175
3176 /* Add Link State Request Retransmission Timer. */
3177 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3178}
3179
3180/* Send Link State Update with an LSA. */
3181void
3182ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3183 int flag)
3184{
hasso52dc7ee2004-09-23 19:18:23 +00003185 struct list *update;
paul718e3742002-12-13 20:15:29 +00003186
3187 update = list_new ();
3188
3189 listnode_add (update, lsa);
3190 ospf_ls_upd_send (nbr, update, flag);
3191
3192 list_delete (update);
3193}
3194
paul68b73392004-09-12 14:21:37 +00003195/* Determine size for packet. Must be at least big enough to accomodate next
3196 * LSA on list, which may be bigger than MTU size.
3197 *
3198 * Return pointer to new ospf_packet
3199 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3200 * on packet sizes (in which case offending LSA is deleted from update list)
3201 */
3202static struct ospf_packet *
3203ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3204{
3205 struct ospf_lsa *lsa;
3206 struct listnode *ln;
3207 size_t size;
3208 static char warned = 0;
3209
paul1eb8ef22005-04-07 07:30:20 +00003210 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003211 assert (lsa->data);
3212
3213 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3214 > ospf_packet_max (oi))
3215 {
3216 if (!warned)
3217 {
3218 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3219 "will need to fragment. Not optimal. Try divide up"
3220 " your network with areas. Use 'debug ospf packet send'"
3221 " to see details, or look at 'show ip ospf database ..'");
3222 warned = 1;
3223 }
3224
3225 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003226 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003227 " %d bytes originated by %s, will be fragmented!",
3228 inet_ntoa (lsa->data->id),
3229 ntohs (lsa->data->length),
3230 inet_ntoa (lsa->data->adv_router));
3231
3232 /*
3233 * Allocate just enough to fit this LSA only, to avoid including other
3234 * LSAs in fragmented LSA Updates.
3235 */
3236 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3237 + OSPF_LS_UPD_MIN_SIZE;
3238 }
3239 else
3240 size = oi->ifp->mtu;
3241
gdt86f1fd92005-01-10 14:20:43 +00003242 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003243 if (size > OSPF_MAX_PACKET_SIZE)
3244 {
3245 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003246 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003247 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003248 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003249 (long int) size);
paul68b73392004-09-12 14:21:37 +00003250 list_delete_node (update, ln);
3251 return NULL;
3252 }
3253
3254 return ospf_packet_new (size);
3255}
3256
paul718e3742002-12-13 20:15:29 +00003257static void
hasso52dc7ee2004-09-23 19:18:23 +00003258ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003259 struct in_addr addr)
3260{
3261 struct ospf_packet *op;
3262 u_int16_t length = OSPF_HEADER_SIZE;
3263
3264 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003265 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003266
3267 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003268
3269 /* Prepare OSPF common header. */
3270 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3271
paul59ea14c2004-07-14 20:50:36 +00003272 /* Prepare OSPF Link State Update body.
3273 * Includes Type-7 translation.
3274 */
paul718e3742002-12-13 20:15:29 +00003275 length += ospf_make_ls_upd (oi, update, op->s);
3276
3277 /* Fill OSPF header. */
3278 ospf_fill_header (oi, op->s, length);
3279
3280 /* Set packet length. */
3281 op->length = length;
3282
3283 /* Decide destination address. */
3284 op->dst.s_addr = addr.s_addr;
3285
3286 /* Add packet to the interface output queue. */
3287 ospf_packet_add (oi, op);
3288
3289 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003290 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003291}
3292
3293static int
3294ospf_ls_upd_send_queue_event (struct thread *thread)
3295{
3296 struct ospf_interface *oi = THREAD_ARG(thread);
3297 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003298 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003299 struct list *update;
paul68b73392004-09-12 14:21:37 +00003300 char again = 0;
paul718e3742002-12-13 20:15:29 +00003301
3302 oi->t_ls_upd_event = NULL;
3303
3304 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003305 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003306
paul736d3442003-07-24 23:22:57 +00003307 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003308 {
paul736d3442003-07-24 23:22:57 +00003309 rnext = route_next (rn);
3310
paul718e3742002-12-13 20:15:29 +00003311 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003312 continue;
paul68b73392004-09-12 14:21:37 +00003313
3314 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003315
paul48fe13b2004-07-27 17:40:44 +00003316 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003317
paul68b73392004-09-12 14:21:37 +00003318 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003319 if (listcount(update) == 0)
3320 {
3321 list_delete (rn->info);
3322 rn->info = NULL;
3323 route_unlock_node (rn);
3324 }
3325 else
paul68b73392004-09-12 14:21:37 +00003326 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003327 }
3328
3329 if (again != 0)
3330 {
3331 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003332 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003333 " %d nodes to try again, raising new event", again);
3334 oi->t_ls_upd_event =
3335 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003336 }
3337
3338 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003339 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003340
paul718e3742002-12-13 20:15:29 +00003341 return 0;
3342}
3343
3344void
hasso52dc7ee2004-09-23 19:18:23 +00003345ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003346{
3347 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003348 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003349 struct prefix_ipv4 p;
3350 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003351 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003352
3353 oi = nbr->oi;
3354
3355 p.family = AF_INET;
3356 p.prefixlen = IPV4_MAX_BITLEN;
3357
3358 /* Decide destination address. */
3359 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3360 p.prefix = oi->vl_data->peer_addr;
3361 else if (flag == OSPF_SEND_PACKET_DIRECT)
3362 p.prefix = nbr->address.u.prefix4;
3363 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3364 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3365 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3366 && (flag == OSPF_SEND_PACKET_INDIRECT))
3367 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003368 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3369 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003370 else
3371 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3372
3373 if (oi->type == OSPF_IFTYPE_NBMA)
3374 {
3375 if (flag == OSPF_SEND_PACKET_INDIRECT)
3376 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3377 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3378 zlog_warn ("* LS-Update is sent to myself.");
3379 }
3380
3381 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3382
3383 if (rn->info == NULL)
3384 rn->info = list_new ();
3385
paul1eb8ef22005-04-07 07:30:20 +00003386 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3387 {
3388 ospf_lsa_lock (lsa);
3389 listnode_add (rn->info, lsa);
3390 }
paul718e3742002-12-13 20:15:29 +00003391
3392 if (oi->t_ls_upd_event == NULL)
3393 oi->t_ls_upd_event =
3394 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3395}
3396
3397static void
hasso52dc7ee2004-09-23 19:18:23 +00003398ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3399 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003400{
3401 struct ospf_packet *op;
3402 u_int16_t length = OSPF_HEADER_SIZE;
3403
3404 op = ospf_packet_new (oi->ifp->mtu);
3405
3406 /* Prepare OSPF common header. */
3407 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3408
3409 /* Prepare OSPF Link State Acknowledgment body. */
3410 length += ospf_make_ls_ack (oi, ack, op->s);
3411
3412 /* Fill OSPF header. */
3413 ospf_fill_header (oi, op->s, length);
3414
3415 /* Set packet length. */
3416 op->length = length;
3417
3418 /* Set destination IP address. */
3419 op->dst = dst;
3420
3421 /* Add packet to the interface output queue. */
3422 ospf_packet_add (oi, op);
3423
3424 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003425 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003426}
3427
3428static int
3429ospf_ls_ack_send_event (struct thread *thread)
3430{
3431 struct ospf_interface *oi = THREAD_ARG (thread);
3432
3433 oi->t_ls_ack_direct = NULL;
3434
3435 while (listcount (oi->ls_ack_direct.ls_ack))
3436 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3437 oi->ls_ack_direct.dst);
3438
3439 return 0;
3440}
3441
3442void
3443ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3444{
3445 struct ospf_interface *oi = nbr->oi;
3446
3447 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3448 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3449
3450 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3451
3452 if (oi->t_ls_ack_direct == NULL)
3453 oi->t_ls_ack_direct =
3454 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3455}
3456
3457/* Send Link State Acknowledgment delayed. */
3458void
3459ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3460{
3461 struct in_addr dst;
3462
3463 /* Decide destination address. */
3464 /* RFC2328 Section 13.5 On non-broadcast
3465 networks, delayed Link State Acknowledgment packets must be
3466 unicast separately over each adjacency (i.e., neighbor whose
3467 state is >= Exchange). */
3468 if (oi->type == OSPF_IFTYPE_NBMA)
3469 {
3470 struct ospf_neighbor *nbr;
3471 struct route_node *rn;
3472
3473 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3474 if ((nbr = rn->info) != NULL)
3475 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3476 while (listcount (oi->ls_ack))
3477 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3478 return;
3479 }
3480 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3481 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3482 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3483 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3484 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3485 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003486 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3487 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003488 else
3489 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3490
3491 while (listcount (oi->ls_ack))
3492 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3493}