blob: 8b818d7230ac41ef1cc2c29403f3ab56b2e0ac78 [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;
paul36238142005-10-11 04:12:54 +0000332 const u_int8_t *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)))
paul36238142005-10-11 04:12:54 +0000348 auth_key = (const u_int8_t *) "";
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;
paul718e3742002-12-13 20:15:29 +0000420 int retransmit_interval;
421
paul718e3742002-12-13 20:15:29 +0000422 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
423
424 lsdb = &nbr->ls_rxmt;
425 update = list_new ();
426
427 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
428 {
429 struct route_table *table = lsdb->type[i].db;
430 struct route_node *rn;
431
432 for (rn = route_top (table); rn; rn = route_next (rn))
433 {
434 struct ospf_lsa *lsa;
435
436 if ((lsa = rn->info) != NULL)
437 /* Don't retransmit an LSA if we received it within
438 the last RxmtInterval seconds - this is to allow the
439 neighbour a chance to acknowledge the LSA as it may
440 have ben just received before the retransmit timer
441 fired. This is a small tweak to what is in the RFC,
442 but it will cut out out a lot of retransmit traffic
443 - MAG */
pauld24f6e22005-10-21 09:23:12 +0000444 if (tv_cmp (tv_sub (recent_time, lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000445 int2tv (retransmit_interval)) >= 0)
446 listnode_add (update, rn->info);
447 }
448 }
449
450 if (listcount (update) > 0)
451 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
452 list_delete (update);
453 }
454
455 /* Set LS Update retransmission timer. */
456 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
457
458 return 0;
459}
460
461int
462ospf_ls_ack_timer (struct thread *thread)
463{
464 struct ospf_interface *oi;
465
466 oi = THREAD_ARG (thread);
467 oi->t_ls_ack = NULL;
468
469 /* Send Link State Acknowledgment. */
470 if (listcount (oi->ls_ack) > 0)
471 ospf_ls_ack_send_delayed (oi);
472
473 /* Set LS Ack timer. */
474 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
475
476 return 0;
477}
478
paul0bfeca32004-09-24 08:07:54 +0000479#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000480static void
paul6a99f832004-09-27 12:56:30 +0000481ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000482 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000483 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000484{
485#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000486 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000487 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000488 int ret;
paul0bfeca32004-09-24 08:07:54 +0000489
490 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000491 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000492
493 /* we can but try.
494 *
495 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
496 * well as the IP_MF flag, making this all quite pointless.
497 *
498 * However, for a system on which IP_MF is left alone, and ip_id left
499 * alone or else which sets same ip_id for each fragment this might
500 * work, eg linux.
501 *
502 * XXX-TODO: It would be much nicer to have the kernel's use their
503 * existing fragmentation support to do this for us. Bugs/RFEs need to
504 * be raised against the various kernels.
505 */
506
507 /* set More Frag */
508 iph->ip_off |= IP_MF;
509
510 /* ip frag offset is expressed in units of 8byte words */
511 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
512
paul62d8e962004-11-02 20:26:45 +0000513 iovp = &msg->msg_iov[1];
514
paul0bfeca32004-09-24 08:07:54 +0000515 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
516 > maxdatasize )
517 {
518 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000519 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
520 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000521 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000522
paul18b12c32004-10-05 14:38:29 +0000523 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000524
paul6a99f832004-09-27 12:56:30 +0000525 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000526
paul18b12c32004-10-05 14:38:29 +0000527 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000528
529 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000530 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000531 " id %d, off %d, len %d, mtu %u failed with %s",
532 inet_ntoa (iph->ip_dst),
533 iph->ip_id,
534 iph->ip_off,
535 iph->ip_len,
536 mtu,
537 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000538
paul37ccfa32004-10-31 11:24:51 +0000539 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
540 {
ajs2a42e282004-12-08 18:43:03 +0000541 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000542 iph->ip_id, iph->ip_off, iph->ip_len,
543 inet_ntoa (iph->ip_dst));
544 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
545 {
ajs2a42e282004-12-08 18:43:03 +0000546 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000547 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000548 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000549 }
550 }
551
paul0bfeca32004-09-24 08:07:54 +0000552 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000553 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000554 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000555 }
556
557 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000558 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
559 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000560 iph->ip_off &= (~IP_MF);
561}
562#endif /* WANT_OSPF_WRITE_FRAGMENT */
563
ajs5dcbdf82005-03-29 16:13:49 +0000564static int
paul718e3742002-12-13 20:15:29 +0000565ospf_write (struct thread *thread)
566{
paul68980082003-03-25 05:07:42 +0000567 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000568 struct ospf_interface *oi;
569 struct ospf_packet *op;
570 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000571 struct ip iph;
572 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000573 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000574 u_char type;
575 int ret;
576 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000577 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000578#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000579 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000580#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000581 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000582#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000583
paul68980082003-03-25 05:07:42 +0000584 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000585
paul68980082003-03-25 05:07:42 +0000586 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000587 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000588 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000589 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000590
591#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000592 /* seed ipid static with low order bits of time */
593 if (ipid == 0)
594 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000595#endif /* WANT_OSPF_WRITE_FRAGMENT */
596
paul68b73392004-09-12 14:21:37 +0000597 /* convenience - max OSPF data per packet */
598 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
599
paul718e3742002-12-13 20:15:29 +0000600 /* Get one packet from queue. */
601 op = ospf_fifo_head (oi->obuf);
602 assert (op);
603 assert (op->length >= OSPF_HEADER_SIZE);
604
paul68980082003-03-25 05:07:42 +0000605 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
606 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000607 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
608
paul718e3742002-12-13 20:15:29 +0000609 /* Rewrite the md5 signature & update the seq */
610 ospf_make_md5_digest (oi, op);
611
paul37ccfa32004-10-31 11:24:51 +0000612 /* Retrieve OSPF packet type. */
613 stream_set_getp (op->s, 1);
614 type = stream_getc (op->s);
615
paul68b73392004-09-12 14:21:37 +0000616 /* reset get pointer */
617 stream_set_getp (op->s, 0);
618
619 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000620 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000621
paul718e3742002-12-13 20:15:29 +0000622 sa_dst.sin_family = AF_INET;
623#ifdef HAVE_SIN_LEN
624 sa_dst.sin_len = sizeof(sa_dst);
625#endif /* HAVE_SIN_LEN */
626 sa_dst.sin_addr = op->dst;
627 sa_dst.sin_port = htons (0);
628
629 /* Set DONTROUTE flag if dst is unicast. */
630 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
631 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
632 flags = MSG_DONTROUTE;
633
paul68b73392004-09-12 14:21:37 +0000634 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
635 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000636 if ( sizeof (struct ip)
637 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000638 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
639
paul718e3742002-12-13 20:15:29 +0000640 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000641 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000642 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000643
paul0bfeca32004-09-24 08:07:54 +0000644#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000645 /* XXX-MT: not thread-safe at all..
646 * XXX: this presumes this is only programme sending OSPF packets
647 * otherwise, no guarantee ipid will be unique
648 */
649 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000650#endif /* WANT_OSPF_WRITE_FRAGMENT */
651
paul718e3742002-12-13 20:15:29 +0000652 iph.ip_off = 0;
653 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
654 iph.ip_ttl = OSPF_VL_IP_TTL;
655 else
656 iph.ip_ttl = OSPF_IP_TTL;
657 iph.ip_p = IPPROTO_OSPFIGP;
658 iph.ip_sum = 0;
659 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
660 iph.ip_dst.s_addr = op->dst.s_addr;
661
662 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000663 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000664 msg.msg_namelen = sizeof (sa_dst);
665 msg.msg_iov = iov;
666 msg.msg_iovlen = 2;
667 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000668 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
669 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000670 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000671
672 /* Sadly we can not rely on kernels to fragment packets because of either
673 * IP_HDRINCL and/or multicast destination being set.
674 */
paul0bfeca32004-09-24 08:07:54 +0000675#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000676 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000677 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
678 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000679#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000680
681 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000682 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000683 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000684 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000685
686 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000687 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000688 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000689 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000690 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000691
paul718e3742002-12-13 20:15:29 +0000692 /* Show debug sending packet. */
693 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
694 {
695 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
696 {
ajs2a42e282004-12-08 18:43:03 +0000697 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000698 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000699 stream_set_getp (op->s, 0);
700 ospf_packet_dump (op->s);
701 }
702
ajs2a42e282004-12-08 18:43:03 +0000703 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000704 ospf_packet_type_str[type], inet_ntoa (op->dst),
705 IF_NAME (oi));
706
707 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000708 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000709 }
710
711 /* Now delete packet from queue. */
712 ospf_packet_delete (oi);
713
714 if (ospf_fifo_head (oi->obuf) == NULL)
715 {
716 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000717 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000718 }
719
720 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000721 if (!list_isempty (ospf->oi_write_q))
722 ospf->t_write =
723 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000724
725 return 0;
726}
727
728/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000729static void
paul718e3742002-12-13 20:15:29 +0000730ospf_hello (struct ip *iph, struct ospf_header *ospfh,
731 struct stream * s, struct ospf_interface *oi, int size)
732{
733 struct ospf_hello *hello;
734 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000735 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000736 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000737
738 /* increment statistics. */
739 oi->hello_in++;
740
741 hello = (struct ospf_hello *) STREAM_PNT (s);
742
743 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000744 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000745 {
746 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
747 {
ajs2a42e282004-12-08 18:43:03 +0000748 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000749 "dropping.",
750 ospf_packet_type_str[ospfh->type],
751 inet_ntoa (iph->ip_src));
752 }
753 return;
754 }
paul718e3742002-12-13 20:15:29 +0000755
756 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000757 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000758 char buf[3][INET_ADDRSTRLEN];
759 zlog_warn("Warning: ignoring HELLO from router %s sent to %s; we "
760 "should not receive hellos on passive interface %s!",
761 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
762 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
763 inet_ntop(AF_INET, &oi->address->u.prefix4,
764 buf[2], sizeof(buf[2])));
765 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
766 {
767 /* Try to fix multicast membership. */
768 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
769 ospf_if_set_multicast(oi);
770 }
paul718e3742002-12-13 20:15:29 +0000771 return;
paulf2c80652002-12-13 21:44:27 +0000772 }
paul718e3742002-12-13 20:15:29 +0000773
774 /* get neighbor prefix. */
775 p.family = AF_INET;
776 p.prefixlen = ip_masklen (hello->network_mask);
777 p.u.prefix4 = iph->ip_src;
778
779 /* Compare network mask. */
780 /* Checking is ignored for Point-to-Point and Virtual link. */
781 if (oi->type != OSPF_IFTYPE_POINTOPOINT
782 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
783 if (oi->address->prefixlen != p.prefixlen)
784 {
785 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
786 inet_ntoa (ospfh->router_id));
787 return;
788 }
789
paul718e3742002-12-13 20:15:29 +0000790 /* Compare Router Dead Interval. */
791 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
792 {
793 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
794 inet_ntoa (ospfh->router_id));
795 return;
796 }
797
paulf9ad9372005-10-21 00:45:17 +0000798 /* Compare Hello Interval - ignored if fast-hellos are set. */
799 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
800 {
801 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
802 {
803 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
804 inet_ntoa (ospfh->router_id));
805 return;
806 }
807 }
808
paul718e3742002-12-13 20:15:29 +0000809 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000810 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000811 inet_ntoa (ospfh->router_id),
812 ospf_options_dump (hello->options));
813
814 /* Compare options. */
815#define REJECT_IF_TBIT_ON 1 /* XXX */
816#ifdef REJECT_IF_TBIT_ON
817 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
818 {
819 /*
820 * This router does not support non-zero TOS.
821 * Drop this Hello packet not to establish neighbor relationship.
822 */
823 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
824 inet_ntoa (ospfh->router_id));
825 return;
826 }
827#endif /* REJECT_IF_TBIT_ON */
828
829#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000830 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000831 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
832 {
833 /*
834 * This router does know the correct usage of O-bit
835 * the bit should be set in DD packet only.
836 */
837 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
838 inet_ntoa (ospfh->router_id));
839#ifdef STRICT_OBIT_USAGE_CHECK
840 return; /* Reject this packet. */
841#else /* STRICT_OBIT_USAGE_CHECK */
842 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
843#endif /* STRICT_OBIT_USAGE_CHECK */
844 }
845#endif /* HAVE_OPAQUE_LSA */
846
847 /* new for NSSA is to ensure that NP is on and E is off */
848
paul718e3742002-12-13 20:15:29 +0000849 if (oi->area->external_routing == OSPF_AREA_NSSA)
850 {
851 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
852 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
853 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
854 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
855 {
856 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
857 return;
858 }
859 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000860 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000861 }
862 else
paul718e3742002-12-13 20:15:29 +0000863 /* The setting of the E-bit found in the Hello Packet's Options
864 field must match this area's ExternalRoutingCapability A
865 mismatch causes processing to stop and the packet to be
866 dropped. The setting of the rest of the bits in the Hello
867 Packet's Options field should be ignored. */
868 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
869 CHECK_FLAG (hello->options, OSPF_OPTION_E))
870 {
ajs3aa8d5f2004-12-11 18:00:06 +0000871 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
872 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000873 return;
874 }
paul718e3742002-12-13 20:15:29 +0000875
pauld3f0d622004-05-05 15:27:15 +0000876 /* get neighbour struct */
877 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
878
879 /* neighbour must be valid, ospf_nbr_get creates if none existed */
880 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000881
882 old_state = nbr->state;
883
884 /* Add event to thread. */
885 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
886
887 /* RFC2328 Section 9.5.1
888 If the router is not eligible to become Designated Router,
889 (snip) It must also send an Hello Packet in reply to an
890 Hello Packet received from any eligible neighbor (other than
891 the current Designated Router and Backup Designated Router). */
892 if (oi->type == OSPF_IFTYPE_NBMA)
893 if (PRIORITY(oi) == 0 && hello->priority > 0
894 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
895 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
896 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
897 OSPF_HELLO_REPLY_DELAY);
898
899 /* on NBMA network type, it happens to receive bidirectional Hello packet
900 without advance 1-Way Received event.
901 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
902 if (oi->type == OSPF_IFTYPE_NBMA &&
903 (old_state == NSM_Down || old_state == NSM_Attempt))
904 {
905 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
906 nbr->priority = hello->priority;
907 nbr->d_router = hello->d_router;
908 nbr->bd_router = hello->bd_router;
909 return;
910 }
911
paul68980082003-03-25 05:07:42 +0000912 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000913 size - OSPF_HELLO_MIN_SIZE))
914 {
915 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
916 nbr->options |= hello->options;
917 }
918 else
919 {
920 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
921 /* Set neighbor information. */
922 nbr->priority = hello->priority;
923 nbr->d_router = hello->d_router;
924 nbr->bd_router = hello->bd_router;
925 return;
926 }
927
928 /* If neighbor itself declares DR and no BDR exists,
929 cause event BackupSeen */
930 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
931 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
932 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
933
934 /* neighbor itself declares BDR. */
935 if (oi->state == ISM_Waiting &&
936 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
937 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
938
939 /* had not previously. */
940 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
941 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
942 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
943 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
944 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
945
946 /* had not previously. */
947 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
948 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
949 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
950 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
951 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
952
953 /* Neighbor priority check. */
954 if (nbr->priority >= 0 && nbr->priority != hello->priority)
955 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
956
957 /* Set neighbor information. */
958 nbr->priority = hello->priority;
959 nbr->d_router = hello->d_router;
960 nbr->bd_router = hello->bd_router;
961}
962
963/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000964static void
paul718e3742002-12-13 20:15:29 +0000965ospf_db_desc_save_current (struct ospf_neighbor *nbr,
966 struct ospf_db_desc *dd)
967{
968 nbr->last_recv.flags = dd->flags;
969 nbr->last_recv.options = dd->options;
970 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
971}
972
973/* Process rest of DD packet. */
974static void
975ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
976 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
977 u_int16_t size)
978{
979 struct ospf_lsa *new, *find;
980 struct lsa_header *lsah;
981
paul9985f832005-02-09 15:51:56 +0000982 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000983 for (size -= OSPF_DB_DESC_MIN_SIZE;
984 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
985 {
986 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000987 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000988
989 /* Unknown LS type. */
990 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
991 {
ajsbec595a2004-11-30 22:38:43 +0000992 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000993 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
994 return;
995 }
996
997#ifdef HAVE_OPAQUE_LSA
998 if (IS_OPAQUE_LSA (lsah->type)
999 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1000 {
1001 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1002 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1003 return;
1004 }
1005#endif /* HAVE_OPAQUE_LSA */
1006
1007 switch (lsah->type)
1008 {
1009 case OSPF_AS_EXTERNAL_LSA:
1010#ifdef HAVE_OPAQUE_LSA
1011 case OSPF_OPAQUE_AS_LSA:
1012#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001013 /* Check for stub area. Reject if AS-External from stub but
1014 allow if from NSSA. */
1015 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001016 {
1017 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1018 lsah->type, inet_ntoa (lsah->id),
1019 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1020 "STUB" : "NSSA");
1021 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1022 return;
1023 }
1024 break;
1025 default:
1026 break;
1027 }
1028
1029 /* Create LS-request object. */
1030 new = ospf_ls_request_new (lsah);
1031
1032 /* Lookup received LSA, then add LS request list. */
1033 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1034 if (!find || ospf_lsa_more_recent (find, new) < 0)
1035 {
1036 ospf_ls_request_add (nbr, new);
1037 ospf_lsa_discard (new);
1038 }
1039 else
1040 {
1041 /* Received LSA is not recent. */
1042 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001043 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001044 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1045 ospf_lsa_discard (new);
1046 continue;
1047 }
1048 }
1049
1050 /* Master */
1051 if (IS_SET_DD_MS (nbr->dd_flags))
1052 {
1053 nbr->dd_seqnum++;
1054 /* Entire DD packet sent. */
1055 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1056 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1057 else
1058 /* Send new DD packet. */
1059 ospf_db_desc_send (nbr);
1060 }
1061 /* Slave */
1062 else
1063 {
1064 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1065
1066 /* When master's more flags is not set. */
1067 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1068 {
1069 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1070 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1071 }
1072
ajsbec595a2004-11-30 22:38:43 +00001073 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001074 ospf_db_desc_send (nbr);
1075 }
1076
1077 /* Save received neighbor values from DD. */
1078 ospf_db_desc_save_current (nbr, dd);
1079}
1080
paul4dadc292005-05-06 21:37:42 +00001081static int
paul718e3742002-12-13 20:15:29 +00001082ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1083{
1084 /* Is DD duplicated? */
1085 if (dd->options == nbr->last_recv.options &&
1086 dd->flags == nbr->last_recv.flags &&
1087 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1088 return 1;
1089
1090 return 0;
1091}
1092
1093/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001094static void
paul718e3742002-12-13 20:15:29 +00001095ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1096 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1097{
1098 struct ospf_db_desc *dd;
1099 struct ospf_neighbor *nbr;
1100
1101 /* Increment statistics. */
1102 oi->db_desc_in++;
1103
1104 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001105
pauld3f0d622004-05-05 15:27:15 +00001106 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001107 if (nbr == NULL)
1108 {
1109 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1110 inet_ntoa (ospfh->router_id));
1111 return;
1112 }
1113
1114 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001115 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1116 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001117 {
ajs3aa8d5f2004-12-11 18:00:06 +00001118 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1119 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1120 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001121 return;
1122 }
1123
pauld363df22003-06-19 00:26:34 +00001124 /*
1125 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1126 * required. In fact at least JunOS sends DD packets with P bit clear.
1127 * Until proper solution is developped, this hack should help.
1128 *
1129 * Update: According to the RFCs, N bit is specified /only/ for Hello
1130 * options, unfortunately its use in DD options is not specified. Hence some
1131 * implementations follow E-bit semantics and set it in DD options, and some
1132 * treat it as unspecified and hence follow the directive "default for
1133 * options is clear", ie unset.
1134 *
1135 * Reset the flag, as ospfd follows E-bit semantics.
1136 */
1137 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1138 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1139 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1140 {
1141 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001142 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001143 inet_ntoa (nbr->router_id) );
1144 SET_FLAG (dd->options, OSPF_OPTION_NP);
1145 }
pauld363df22003-06-19 00:26:34 +00001146
paul718e3742002-12-13 20:15:29 +00001147#ifdef REJECT_IF_TBIT_ON
1148 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1149 {
1150 /*
1151 * In Hello protocol, optional capability must have checked
1152 * to prevent this T-bit enabled router be my neighbor.
1153 */
1154 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1155 return;
1156 }
1157#endif /* REJECT_IF_TBIT_ON */
1158
1159#ifdef HAVE_OPAQUE_LSA
1160 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001161 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001162 {
1163 /*
1164 * This node is not configured to handle O-bit, for now.
1165 * Clear it to ignore unsupported capability proposed by neighbor.
1166 */
1167 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1168 }
1169#endif /* HAVE_OPAQUE_LSA */
1170
1171 /* Process DD packet by neighbor status. */
1172 switch (nbr->state)
1173 {
1174 case NSM_Down:
1175 case NSM_Attempt:
1176 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001177 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001178 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001179 LOOKUP (ospf_nsm_state_msg, nbr->state));
1180 break;
1181 case NSM_Init:
1182 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1183 /* If the new state is ExStart, the processing of the current
1184 packet should then continue in this new state by falling
1185 through to case ExStart below. */
1186 if (nbr->state != NSM_ExStart)
1187 break;
1188 case NSM_ExStart:
1189 /* Initial DBD */
1190 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1191 (size == OSPF_DB_DESC_MIN_SIZE))
1192 {
paul68980082003-03-25 05:07:42 +00001193 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001194 {
1195 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001196 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001197 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001198 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1199 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1200 }
1201 else
1202 {
1203 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001204 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1205 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001206 break;
1207 }
1208 }
1209 /* Ack from the Slave */
1210 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1211 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001212 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001213 {
ajs17eaa722004-12-29 21:04:48 +00001214 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001215 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001216 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1217 }
1218 else
1219 {
ajs3aa8d5f2004-12-11 18:00:06 +00001220 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1221 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001222 break;
1223 }
1224
1225 /* This is where the real Options are saved */
1226 nbr->options = dd->options;
1227
1228#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001229 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001230 {
1231 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001232 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001233 inet_ntoa (nbr->router_id),
1234 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1235
1236 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1237 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1238 {
1239 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1240 /* This situation is undesirable, but not a real error. */
1241 }
1242 }
1243#endif /* HAVE_OPAQUE_LSA */
1244
1245 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1246
1247 /* continue processing rest of packet. */
1248 ospf_db_desc_proc (s, oi, nbr, dd, size);
1249 break;
1250 case NSM_Exchange:
1251 if (ospf_db_desc_is_dup (dd, nbr))
1252 {
1253 if (IS_SET_DD_MS (nbr->dd_flags))
1254 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001255 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1256 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001257 else
1258 /* Slave: cause to retransmit the last Database Description. */
1259 {
ajs3aa8d5f2004-12-11 18:00:06 +00001260 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1261 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001262 ospf_db_desc_resend (nbr);
1263 }
1264 break;
1265 }
1266
1267 /* Otherwise DD packet should be checked. */
1268 /* Check Master/Slave bit mismatch */
1269 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1270 {
ajs3aa8d5f2004-12-11 18:00:06 +00001271 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1272 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001273 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1274 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001275 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001276 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001277 break;
1278 }
1279
1280 /* Check initialize bit is set. */
1281 if (IS_SET_DD_I (dd->flags))
1282 {
ajs3aa8d5f2004-12-11 18:00:06 +00001283 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1284 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001285 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1286 break;
1287 }
1288
1289 /* Check DD Options. */
1290 if (dd->options != nbr->options)
1291 {
1292#ifdef ORIGINAL_CODING
1293 /* Save the new options for debugging */
1294 nbr->options = dd->options;
1295#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001296 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1297 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001298 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1299 break;
1300 }
1301
1302 /* Check DD sequence number. */
1303 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1304 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1305 (!IS_SET_DD_MS (nbr->dd_flags) &&
1306 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1307 {
ajs3aa8d5f2004-12-11 18:00:06 +00001308 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1309 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001310 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1311 break;
1312 }
1313
1314 /* Continue processing rest of packet. */
1315 ospf_db_desc_proc (s, oi, nbr, dd, size);
1316 break;
1317 case NSM_Loading:
1318 case NSM_Full:
1319 if (ospf_db_desc_is_dup (dd, nbr))
1320 {
1321 if (IS_SET_DD_MS (nbr->dd_flags))
1322 {
1323 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001324 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1325 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001326 break;
1327 }
1328 else
1329 {
1330 struct timeval t, now;
1331 gettimeofday (&now, NULL);
1332 t = tv_sub (now, nbr->last_send_ts);
1333 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1334 {
1335 /* In states Loading and Full the slave must resend
1336 its last Database Description packet in response to
1337 duplicate Database Description packets received
1338 from the master. For this reason the slave must
1339 wait RouterDeadInterval seconds before freeing the
1340 last Database Description packet. Reception of a
1341 Database Description packet from the master after
1342 this interval will generate a SeqNumberMismatch
1343 neighbor event. RFC2328 Section 10.8 */
1344 ospf_db_desc_resend (nbr);
1345 break;
1346 }
1347 }
1348 }
1349
1350 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1351 break;
1352 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001353 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1354 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001355 break;
1356 }
1357}
1358
1359#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1360
1361/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001362static void
paul718e3742002-12-13 20:15:29 +00001363ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1364 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1365{
1366 struct ospf_neighbor *nbr;
1367 u_int32_t ls_type;
1368 struct in_addr ls_id;
1369 struct in_addr adv_router;
1370 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001371 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001372 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001373
1374 /* Increment statistics. */
1375 oi->ls_req_in++;
1376
pauld3f0d622004-05-05 15:27:15 +00001377 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001378 if (nbr == NULL)
1379 {
1380 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1381 inet_ntoa (ospfh->router_id));
1382 return;
1383 }
1384
1385 /* Neighbor State should be Exchange or later. */
1386 if (nbr->state != NSM_Exchange &&
1387 nbr->state != NSM_Loading &&
1388 nbr->state != NSM_Full)
1389 {
ajsbec595a2004-11-30 22:38:43 +00001390 zlog_warn ("Link State Request received from %s: "
1391 "Neighbor state is %s, packet discarded.",
1392 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001393 LOOKUP (ospf_nsm_state_msg, nbr->state));
1394 return;
1395 }
1396
1397 /* Send Link State Update for ALL requested LSAs. */
1398 ls_upd = list_new ();
1399 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1400
1401 while (size >= OSPF_LSA_KEY_SIZE)
1402 {
1403 /* Get one slice of Link State Request. */
1404 ls_type = stream_getl (s);
1405 ls_id.s_addr = stream_get_ipv4 (s);
1406 adv_router.s_addr = stream_get_ipv4 (s);
1407
1408 /* Verify LSA type. */
1409 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1410 {
1411 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1412 list_delete (ls_upd);
1413 return;
1414 }
1415
1416 /* Search proper LSA in LSDB. */
1417 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1418 if (find == NULL)
1419 {
1420 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1421 list_delete (ls_upd);
1422 return;
1423 }
1424
gdt86f1fd92005-01-10 14:20:43 +00001425 /* Packet overflows MTU size, send immediately. */
1426 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001427 {
1428 if (oi->type == OSPF_IFTYPE_NBMA)
1429 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1430 else
1431 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1432
1433 /* Only remove list contents. Keep ls_upd. */
1434 list_delete_all_node (ls_upd);
1435
1436 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1437 }
1438
1439 /* Append LSA to update list. */
1440 listnode_add (ls_upd, find);
1441 length += ntohs (find->data->length);
1442
1443 size -= OSPF_LSA_KEY_SIZE;
1444 }
1445
1446 /* Send rest of Link State Update. */
1447 if (listcount (ls_upd) > 0)
1448 {
1449 if (oi->type == OSPF_IFTYPE_NBMA)
1450 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1451 else
1452 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1453
1454 list_delete (ls_upd);
1455 }
1456 else
1457 list_free (ls_upd);
1458}
1459
1460/* Get the list of LSAs from Link State Update packet.
1461 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001462static struct list *
paul718e3742002-12-13 20:15:29 +00001463ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1464 struct ospf_interface *oi, size_t size)
1465{
1466 u_int16_t count, sum;
1467 u_int32_t length;
1468 struct lsa_header *lsah;
1469 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001470 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001471
1472 lsas = list_new ();
1473
1474 count = stream_getl (s);
1475 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1476
1477 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001478 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001479 {
1480 lsah = (struct lsa_header *) STREAM_PNT (s);
1481 length = ntohs (lsah->length);
1482
1483 if (length > size)
1484 {
1485 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1486 break;
1487 }
1488
1489 /* Validate the LSA's LS checksum. */
1490 sum = lsah->checksum;
1491 if (sum != ospf_lsa_checksum (lsah))
1492 {
1493 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1494 sum, lsah->checksum);
1495 continue;
1496 }
1497
1498 /* Examine the LSA's LS type. */
1499 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1500 {
1501 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1502 continue;
1503 }
1504
1505 /*
1506 * What if the received LSA's age is greater than MaxAge?
1507 * Treat it as a MaxAge case -- endo.
1508 */
1509 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1510 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1511
1512#ifdef HAVE_OPAQUE_LSA
1513 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1514 {
1515#ifdef STRICT_OBIT_USAGE_CHECK
1516 if ((IS_OPAQUE_LSA(lsah->type) &&
1517 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1518 || (! IS_OPAQUE_LSA(lsah->type) &&
1519 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1520 {
1521 /*
1522 * This neighbor must know the exact usage of O-bit;
1523 * the bit will be set in Type-9,10,11 LSAs only.
1524 */
1525 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1526 continue;
1527 }
1528#endif /* STRICT_OBIT_USAGE_CHECK */
1529
1530 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1531 if (lsah->type == OSPF_OPAQUE_AS_LSA
1532 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1533 {
1534 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001535 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 +00001536 continue;
1537 }
1538 }
1539 else if (IS_OPAQUE_LSA(lsah->type))
1540 {
1541 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1542 continue;
1543 }
1544#endif /* HAVE_OPAQUE_LSA */
1545
1546 /* Create OSPF LSA instance. */
1547 lsa = ospf_lsa_new ();
1548
1549 /* We may wish to put some error checking if type NSSA comes in
1550 and area not in NSSA mode */
1551 switch (lsah->type)
1552 {
1553 case OSPF_AS_EXTERNAL_LSA:
1554#ifdef HAVE_OPAQUE_LSA
1555 case OSPF_OPAQUE_AS_LSA:
1556 lsa->area = NULL;
1557 break;
1558 case OSPF_OPAQUE_LINK_LSA:
1559 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1560 /* Fallthrough */
1561#endif /* HAVE_OPAQUE_LSA */
1562 default:
1563 lsa->area = oi->area;
1564 break;
1565 }
1566
1567 lsa->data = ospf_lsa_data_new (length);
1568 memcpy (lsa->data, lsah, length);
1569
1570 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001571 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001572 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1573 listnode_add (lsas, lsa);
1574 }
1575
1576 return lsas;
1577}
1578
1579/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001580static void
hasso52dc7ee2004-09-23 19:18:23 +00001581ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001582{
paul1eb8ef22005-04-07 07:30:20 +00001583 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001584 struct ospf_lsa *lsa;
1585
paul1eb8ef22005-04-07 07:30:20 +00001586 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1587 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001588
1589 list_delete (lsas);
1590}
1591
1592/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001593static void
paul718e3742002-12-13 20:15:29 +00001594ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1595 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1596{
1597 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001598 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001599 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001600 struct ospf_lsa *lsa = NULL;
1601 /* unsigned long ls_req_found = 0; */
1602
1603 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1604
1605 /* Increment statistics. */
1606 oi->ls_upd_in++;
1607
1608 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001609 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001610 if (nbr == NULL)
1611 {
1612 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1613 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1614 return;
1615 }
1616
1617 /* Check neighbor state. */
1618 if (nbr->state < NSM_Exchange)
1619 {
ajs3aa8d5f2004-12-11 18:00:06 +00001620 zlog_warn ("Link State Update: "
1621 "Neighbor[%s] state %s is less than Exchange",
1622 inet_ntoa (ospfh->router_id),
1623 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001624 return;
1625 }
1626
1627 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1628 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1629 * of section 13.
1630 */
1631 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1632
1633#ifdef HAVE_OPAQUE_LSA
1634 /*
paul718e3742002-12-13 20:15:29 +00001635 * If self-originated Opaque-LSAs that have flooded before restart
1636 * are contained in the received LSUpd message, corresponding LSReq
1637 * messages to be sent may have to be modified.
1638 * To eliminate possible race conditions such that flushing and normal
1639 * updating for the same LSA would take place alternately, this trick
1640 * must be done before entering to the loop below.
1641 */
paul69310a62005-05-11 18:09:59 +00001642 /* XXX: Why is this Opaque specific? Either our core code is deficient
1643 * and this should be fixed generally, or Opaque is inventing strawman
1644 * problems */
paul718e3742002-12-13 20:15:29 +00001645 ospf_opaque_adjust_lsreq (nbr, lsas);
1646#endif /* HAVE_OPAQUE_LSA */
1647
1648#define DISCARD_LSA(L,N) {\
1649 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001650 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 +00001651 ospf_lsa_discard (L); \
1652 continue; }
1653
1654 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001655 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001656 {
1657 struct ospf_lsa *ls_ret, *current;
1658 int ret = 1;
1659
paul718e3742002-12-13 20:15:29 +00001660 if (IS_DEBUG_OSPF_NSSA)
1661 {
1662 char buf1[INET_ADDRSTRLEN];
1663 char buf2[INET_ADDRSTRLEN];
1664 char buf3[INET_ADDRSTRLEN];
1665
ajs2a42e282004-12-08 18:43:03 +00001666 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001667 lsa->data->type,
1668 inet_ntop (AF_INET, &ospfh->router_id,
1669 buf1, INET_ADDRSTRLEN),
1670 inet_ntop (AF_INET, &lsa->data->id,
1671 buf2, INET_ADDRSTRLEN),
1672 inet_ntop (AF_INET, &lsa->data->adv_router,
1673 buf3, INET_ADDRSTRLEN));
1674 }
paul718e3742002-12-13 20:15:29 +00001675
1676 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1677
1678 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1679
1680 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1681
1682 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1683
1684 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1685
1686 /* Do take in Type-7's if we are an NSSA */
1687
1688 /* If we are also an ABR, later translate them to a Type-5 packet */
1689
1690 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1691 translate them to a separate Type-5 packet. */
1692
1693 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1694 /* Reject from STUB or NSSA */
1695 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1696 {
1697 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001698 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001699 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001700 }
1701
paul718e3742002-12-13 20:15:29 +00001702 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1703 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1704 {
1705 DISCARD_LSA (lsa,2);
1706 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001707 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001708 }
paul718e3742002-12-13 20:15:29 +00001709
1710 /* Find the LSA in the current database. */
1711
1712 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1713
1714 /* If the LSA's LS age is equal to MaxAge, and there is currently
1715 no instance of the LSA in the router's link state database,
1716 and none of router's neighbors are in states Exchange or Loading,
1717 then take the following actions. */
1718
1719 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001720 (ospf_nbr_count (oi, NSM_Exchange) +
1721 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001722 {
1723 /* Response Link State Acknowledgment. */
1724 ospf_ls_ack_send (nbr, lsa);
1725
1726 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001727 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1728 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001729 DISCARD_LSA (lsa, 3);
1730 }
1731
1732#ifdef HAVE_OPAQUE_LSA
1733 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001734 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001735 {
1736 /*
1737 * Even if initial flushing seems to be completed, there might
1738 * be a case that self-originated LSA with MaxAge still remain
1739 * in the routing domain.
1740 * Just send an LSAck message to cease retransmission.
1741 */
1742 if (IS_LSA_MAXAGE (lsa))
1743 {
1744 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1745 ospf_ls_ack_send (nbr, lsa);
1746 ospf_lsa_discard (lsa);
1747
1748 if (current != NULL && ! IS_LSA_MAXAGE (current))
1749 ospf_opaque_lsa_refresh_schedule (current);
1750 continue;
1751 }
1752
1753 /*
1754 * If an instance of self-originated Opaque-LSA is not found
1755 * in the LSDB, there are some possible cases here.
1756 *
1757 * 1) This node lost opaque-capability after restart.
1758 * 2) Else, a part of opaque-type is no more supported.
1759 * 3) Else, a part of opaque-id is no more supported.
1760 *
1761 * Anyway, it is still this node's responsibility to flush it.
1762 * Otherwise, the LSA instance remains in the routing domain
1763 * until its age reaches to MaxAge.
1764 */
paul69310a62005-05-11 18:09:59 +00001765 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001766 if (current == NULL)
1767 {
1768 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001769 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1770 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001771
1772 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001773
1774 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1775 ospf_ls_ack_send (nbr, lsa);
1776
paul718e3742002-12-13 20:15:29 +00001777 continue;
1778 }
1779 }
1780#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001781
hassocb05eb22004-02-11 21:10:19 +00001782 /* It might be happen that received LSA is self-originated network LSA, but
1783 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1784 * Link State ID is one of the router's own IP interface addresses but whose
1785 * Advertising Router is not equal to the router's own Router ID
1786 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1787 */
1788
1789 if(lsa->data->type == OSPF_NETWORK_LSA)
1790 {
paul1eb8ef22005-04-07 07:30:20 +00001791 struct listnode *oinode, *oinnode;
1792 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001793 int Flag = 0;
1794
paul1eb8ef22005-04-07 07:30:20 +00001795 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001796 {
hassocb05eb22004-02-11 21:10:19 +00001797 if(out_if == NULL)
1798 break;
1799
1800 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1801 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1802 {
1803 if(out_if->network_lsa_self)
1804 {
1805 ospf_lsa_flush_area(lsa,out_if->area);
1806 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001807 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001808 lsa, (int) lsa->data->type);
1809 ospf_lsa_discard (lsa);
1810 Flag = 1;
1811 }
1812 break;
1813 }
1814 }
1815 if(Flag)
1816 continue;
1817 }
paul718e3742002-12-13 20:15:29 +00001818
1819 /* (5) Find the instance of this LSA that is currently contained
1820 in the router's link state database. If there is no
1821 database copy, or the received LSA is more recent than
1822 the database copy the following steps must be performed. */
1823
1824 if (current == NULL ||
1825 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1826 {
1827 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001828 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001829 DISCARD_LSA (lsa, 4);
1830 continue;
1831 }
1832
1833 /* (6) Else, If there is an instance of the LSA on the sending
1834 neighbor's Link state request list, an error has occurred in
1835 the Database Exchange process. In this case, restart the
1836 Database Exchange process by generating the neighbor event
1837 BadLSReq for the sending neighbor and stop processing the
1838 Link State Update packet. */
1839
1840 if (ospf_ls_request_lookup (nbr, lsa))
1841 {
1842 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001843 zlog_warn("LSA[%s] instance exists on Link state request list",
1844 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001845
1846 /* Clean list of LSAs. */
1847 ospf_upd_list_clean (lsas);
1848 /* this lsa is not on lsas list already. */
1849 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001850 return;
1851 }
1852
1853 /* If the received LSA is the same instance as the database copy
1854 (i.e., neither one is more recent) the following two steps
1855 should be performed: */
1856
1857 if (ret == 0)
1858 {
1859 /* If the LSA is listed in the Link state retransmission list
1860 for the receiving adjacency, the router itself is expecting
1861 an acknowledgment for this LSA. The router should treat the
1862 received LSA as an acknowledgment by removing the LSA from
1863 the Link state retransmission list. This is termed an
1864 "implied acknowledgment". */
1865
1866 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1867
1868 if (ls_ret != NULL)
1869 {
1870 ospf_ls_retransmit_delete (nbr, ls_ret);
1871
1872 /* Delayed acknowledgment sent if advertisement received
1873 from Designated Router, otherwise do nothing. */
1874 if (oi->state == ISM_Backup)
1875 if (NBR_IS_DR (nbr))
1876 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1877
1878 DISCARD_LSA (lsa, 5);
1879 }
1880 else
1881 /* Acknowledge the receipt of the LSA by sending a
1882 Link State Acknowledgment packet back out the receiving
1883 interface. */
1884 {
1885 ospf_ls_ack_send (nbr, lsa);
1886 DISCARD_LSA (lsa, 6);
1887 }
1888 }
1889
1890 /* The database copy is more recent. If the database copy
1891 has LS age equal to MaxAge and LS sequence number equal to
1892 MaxSequenceNumber, simply discard the received LSA without
1893 acknowledging it. (In this case, the LSA's LS sequence number is
1894 wrapping, and the MaxSequenceNumber LSA must be completely
1895 flushed before any new LSA instance can be introduced). */
1896
1897 else if (ret > 0) /* Database copy is more recent */
1898 {
1899 if (IS_LSA_MAXAGE (current) &&
1900 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1901 {
1902 DISCARD_LSA (lsa, 7);
1903 }
1904 /* Otherwise, as long as the database copy has not been sent in a
1905 Link State Update within the last MinLSArrival seconds, send the
1906 database copy back to the sending neighbor, encapsulated within
1907 a Link State Update Packet. The Link State Update Packet should
1908 be sent directly to the neighbor. In so doing, do not put the
1909 database copy of the LSA on the neighbor's link state
1910 retransmission list, and do not acknowledge the received (less
1911 recent) LSA instance. */
1912 else
1913 {
1914 struct timeval now;
1915
1916 gettimeofday (&now, NULL);
1917
1918 if (tv_cmp (tv_sub (now, current->tv_orig),
1919 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1920 /* Trap NSSA type later.*/
1921 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1922 DISCARD_LSA (lsa, 8);
1923 }
1924 }
1925 }
1926
paul718e3742002-12-13 20:15:29 +00001927 assert (listcount (lsas) == 0);
1928 list_delete (lsas);
1929}
1930
1931/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001932static void
paul718e3742002-12-13 20:15:29 +00001933ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1934 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1935{
1936 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001937
paul718e3742002-12-13 20:15:29 +00001938 /* increment statistics. */
1939 oi->ls_ack_in++;
1940
pauld3f0d622004-05-05 15:27:15 +00001941 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001942 if (nbr == NULL)
1943 {
1944 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1945 inet_ntoa (ospfh->router_id));
1946 return;
1947 }
1948
1949 if (nbr->state < NSM_Exchange)
1950 {
ajs3aa8d5f2004-12-11 18:00:06 +00001951 zlog_warn ("Link State Acknowledgment: "
1952 "Neighbor[%s] state %s is less than Exchange",
1953 inet_ntoa (ospfh->router_id),
1954 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001955 return;
1956 }
paul69310a62005-05-11 18:09:59 +00001957
paul718e3742002-12-13 20:15:29 +00001958 while (size >= OSPF_LSA_HEADER_SIZE)
1959 {
1960 struct ospf_lsa *lsa, *lsr;
1961
1962 lsa = ospf_lsa_new ();
1963 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1964
1965 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1966 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00001967 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001968
1969 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1970 {
1971 lsa->data = NULL;
1972 ospf_lsa_discard (lsa);
1973 continue;
1974 }
1975
1976 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1977
1978 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1979 {
1980#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001981 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00001982 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00001983#endif /* HAVE_OPAQUE_LSA */
1984
1985 ospf_ls_retransmit_delete (nbr, lsr);
1986 }
1987
1988 lsa->data = NULL;
1989 ospf_lsa_discard (lsa);
1990 }
1991
paul718e3742002-12-13 20:15:29 +00001992 return;
paul718e3742002-12-13 20:15:29 +00001993}
1994
ajs038163f2005-02-17 19:55:59 +00001995static struct stream *
ajs5c333492005-02-23 15:43:01 +00001996ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00001997{
1998 int ret;
ajs5c333492005-02-23 15:43:01 +00001999 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002000 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002001 unsigned int ifindex = 0;
2002 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002003 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002004 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002005 struct msghdr msgh;
2006
paul68defd62004-09-27 07:27:13 +00002007 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002008 msgh.msg_iov = &iov;
2009 msgh.msg_iovlen = 1;
2010 msgh.msg_control = (caddr_t) buff;
2011 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002012
ajs5c333492005-02-23 15:43:01 +00002013 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2014 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002015 {
ajs5c333492005-02-23 15:43:01 +00002016 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2017 return NULL;
2018 }
paul69310a62005-05-11 18:09:59 +00002019 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002020 {
2021 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2022 "(ip header size is %u)",
2023 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002024 return NULL;
2025 }
paul18b12c32004-10-05 14:38:29 +00002026
ajs5c333492005-02-23 15:43:01 +00002027 /* Note that there should not be alignment problems with this assignment
2028 because this is at the beginning of the stream data buffer. */
2029 iph = (struct ip *) STREAM_DATA(ibuf);
2030 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002031
ajs5c333492005-02-23 15:43:01 +00002032 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002033
paul239aecc2003-12-08 10:34:54 +00002034#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002035 /*
2036 * Kernel network code touches incoming IP header parameters,
2037 * before protocol specific processing.
2038 *
2039 * 1) Convert byteorder to host representation.
2040 * --> ip_len, ip_id, ip_off
2041 *
2042 * 2) Adjust ip_len to strip IP header size!
2043 * --> If user process receives entire IP packet via RAW
2044 * socket, it must consider adding IP header size to
2045 * the "ip_len" field of "ip" structure.
2046 *
2047 * For more details, see <netinet/ip_input.c>.
2048 */
ajs5c333492005-02-23 15:43:01 +00002049 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002050#endif
2051
paul863082d2004-08-19 04:43:43 +00002052 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002053
2054 *ifp = if_lookup_by_index (ifindex);
2055
2056 if (ret != ip_len)
2057 {
ajs5c333492005-02-23 15:43:01 +00002058 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2059 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002060 return NULL;
2061 }
2062
2063 return ibuf;
2064}
2065
paul4dadc292005-05-06 21:37:42 +00002066static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002067ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002068 struct ip *iph, struct ospf_header *ospfh)
2069{
2070 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002071 struct ospf_vl_data *vl_data;
2072 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002073 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002074
2075 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2076 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002077 return NULL;
paul718e3742002-12-13 20:15:29 +00002078
pauld3f0d622004-05-05 15:27:15 +00002079 /* look for local OSPF interface matching the destination
2080 * to determine Area ID. We presume therefore the destination address
2081 * is unique, or at least (for "unnumbered" links), not used in other
2082 * areas
2083 */
2084 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2085 iph->ip_dst)) == NULL)
2086 return NULL;
paul718e3742002-12-13 20:15:29 +00002087
paul1eb8ef22005-04-07 07:30:20 +00002088 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002089 {
paul020709f2003-04-04 02:44:16 +00002090 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002091 if (!vl_area)
2092 continue;
2093
2094 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2095 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2096 {
2097 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002098 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002099 IF_NAME (vl_data->vl_oi));
2100 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2101 {
2102 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002103 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002104 return NULL;
2105 }
2106
2107 return vl_data->vl_oi;
2108 }
2109 }
2110
2111 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002112 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002113
pauld3f0d622004-05-05 15:27:15 +00002114 return NULL;
paul718e3742002-12-13 20:15:29 +00002115}
2116
paul4dadc292005-05-06 21:37:42 +00002117static inline int
paul718e3742002-12-13 20:15:29 +00002118ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2119{
2120 /* Check match the Area ID of the receiving interface. */
2121 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2122 return 1;
2123
2124 return 0;
2125}
2126
2127/* Unbound socket will accept any Raw IP packets if proto is matched.
2128 To prevent it, compare src IP address and i/f address with masking
2129 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002130static int
paul718e3742002-12-13 20:15:29 +00002131ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2132{
2133 struct in_addr mask, me, him;
2134
2135 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2136 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2137 return 1;
2138
2139 masklen2ip (oi->address->prefixlen, &mask);
2140
2141 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2142 him.s_addr = ip_src.s_addr & mask.s_addr;
2143
2144 if (IPV4_ADDR_SAME (&me, &him))
2145 return 1;
2146
2147 return 0;
2148}
2149
paul4dadc292005-05-06 21:37:42 +00002150static int
paul718e3742002-12-13 20:15:29 +00002151ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2152 struct ospf_header *ospfh)
2153{
2154 int ret = 0;
2155 struct crypt_key *ck;
2156
2157 switch (ntohs (ospfh->auth_type))
2158 {
2159 case OSPF_AUTH_NULL:
2160 ret = 1;
2161 break;
2162 case OSPF_AUTH_SIMPLE:
2163 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2164 ret = 1;
2165 else
2166 ret = 0;
2167 break;
2168 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002169 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002170 {
2171 ret = 0;
2172 break;
2173 }
2174
2175 /* This is very basic, the digest processing is elsewhere */
2176 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2177 ospfh->u.crypt.key_id == ck->key_id &&
2178 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2179 ret = 1;
2180 else
2181 ret = 0;
2182 break;
2183 default:
2184 ret = 0;
2185 break;
2186 }
2187
2188 return ret;
2189}
2190
paul4dadc292005-05-06 21:37:42 +00002191static int
paul718e3742002-12-13 20:15:29 +00002192ospf_check_sum (struct ospf_header *ospfh)
2193{
2194 u_int32_t ret;
2195 u_int16_t sum;
2196 int in_cksum (void *ptr, int nbytes);
2197
2198 /* clear auth_data for checksum. */
2199 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2200
2201 /* keep checksum and clear. */
2202 sum = ospfh->checksum;
2203 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2204
2205 /* calculate checksum. */
2206 ret = in_cksum (ospfh, ntohs (ospfh->length));
2207
2208 if (ret != sum)
2209 {
2210 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2211 ret, sum);
2212 return 0;
2213 }
2214
2215 return 1;
2216}
2217
2218/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002219static int
paul718e3742002-12-13 20:15:29 +00002220ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2221 struct ip *iph, struct ospf_header *ospfh)
2222{
2223 /* check version. */
2224 if (ospfh->version != OSPF_VERSION)
2225 {
2226 zlog_warn ("interface %s: ospf_read version number mismatch.",
2227 IF_NAME (oi));
2228 return -1;
2229 }
2230
2231 /* Check Area ID. */
2232 if (!ospf_check_area_id (oi, ospfh))
2233 {
2234 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2235 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2236 return -1;
2237 }
2238
2239 /* Check network mask, Silently discarded. */
2240 if (! ospf_check_network_mask (oi, iph->ip_src))
2241 {
2242 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2243 IF_NAME (oi), inet_ntoa (iph->ip_src));
2244 return -1;
2245 }
2246
2247 /* Check authentication. */
2248 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2249 {
2250 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2251 IF_NAME (oi));
2252 return -1;
2253 }
2254
2255 if (! ospf_check_auth (oi, ibuf, ospfh))
2256 {
2257 zlog_warn ("interface %s: ospf_read authentication failed.",
2258 IF_NAME (oi));
2259 return -1;
2260 }
2261
2262 /* if check sum is invalid, packet is discarded. */
2263 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2264 {
2265 if (! ospf_check_sum (ospfh))
2266 {
2267 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2268 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2269 return -1;
2270 }
2271 }
2272 else
2273 {
2274 if (ospfh->checksum != 0)
2275 return -1;
2276 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2277 {
2278 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2279 IF_NAME (oi));
2280 return -1;
2281 }
2282 }
2283
2284 return 0;
2285}
2286
2287/* Starting point of packet process function. */
2288int
2289ospf_read (struct thread *thread)
2290{
2291 int ret;
2292 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002293 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002294 struct ospf_interface *oi;
2295 struct ip *iph;
2296 struct ospf_header *ospfh;
2297 u_int16_t length;
2298 struct interface *ifp;
2299
2300 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002301 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002302
2303 /* prepare for next packet. */
2304 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002305
2306 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002307 stream_reset(ospf->ibuf);
2308 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002309 return -1;
2310
ajs5c333492005-02-23 15:43:01 +00002311 /* Note that there should not be alignment problems with this assignment
2312 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002313 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002314 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002315
paulac191232004-10-22 12:05:17 +00002316 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002317 /* Handle cases where the platform does not support retrieving the ifindex,
2318 and also platforms (such as Solaris 8) that claim to support ifindex
2319 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002320 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002321
pauld3f0d622004-05-05 15:27:15 +00002322 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002323 return 0;
paul718e3742002-12-13 20:15:29 +00002324
2325 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002326 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002327 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002328
paul718e3742002-12-13 20:15:29 +00002329 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002330 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002331 {
pauld3241812003-09-29 12:42:39 +00002332 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2333 {
ajs2a42e282004-12-08 18:43:03 +00002334 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002335 inet_ntoa (iph->ip_src));
2336 }
paul718e3742002-12-13 20:15:29 +00002337 return 0;
2338 }
2339
2340 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002341 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002342
2343 /* Get ospf packet header. */
2344 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2345
2346 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002347 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002348
2349 /* if no local ospf_interface,
2350 * or header area is backbone but ospf_interface is not
2351 * check for VLINK interface
2352 */
2353 if ( (oi == NULL) ||
2354 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2355 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2356 )
2357 {
2358 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2359 {
paulf9ad9372005-10-21 00:45:17 +00002360 zlog_debug ("Packet from [%s] received on link %s"
pauld3f0d622004-05-05 15:27:15 +00002361 " but no ospf_interface",
2362 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002363 return 0;
2364 }
2365 }
2366
2367 /* else it must be a local ospf interface, check it was received on
2368 * correct link
2369 */
2370 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002371 {
2372 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002373 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002374 return 0;
2375 }
ajs847947f2005-02-02 18:38:48 +00002376 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002377 {
ajsba6454e2005-02-08 15:37:30 +00002378 char buf[2][INET_ADDRSTRLEN];
2379 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002380 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002381 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2382 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2383 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002384 /* Fix multicast memberships? */
2385 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2386 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2387 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2388 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2389 if (oi->multicast_memberships)
2390 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002391 return 0;
2392 }
paul718e3742002-12-13 20:15:29 +00002393
2394 /*
2395 * If the received packet is destined for AllDRouters, the packet
2396 * should be accepted only if the received ospf interface state is
2397 * either DR or Backup -- endo.
2398 */
2399 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2400 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2401 {
ajsba6454e2005-02-08 15:37:30 +00002402 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002403 inet_ntoa (iph->ip_src), IF_NAME (oi),
2404 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002405 /* Try to fix multicast membership. */
2406 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2407 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002408 return 0;
2409 }
2410
2411 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002412 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2413 {
paul718e3742002-12-13 20:15:29 +00002414 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002415 {
ajs2a42e282004-12-08 18:43:03 +00002416 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002417 ospf_packet_dump (ibuf);
2418 }
paul718e3742002-12-13 20:15:29 +00002419
ajs2a42e282004-12-08 18:43:03 +00002420 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002421 ospf_packet_type_str[ospfh->type],
2422 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002423 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2424 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002425
2426 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002427 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002428 }
paul718e3742002-12-13 20:15:29 +00002429
2430 /* Some header verification. */
2431 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2432 if (ret < 0)
2433 {
pauld3241812003-09-29 12:42:39 +00002434 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2435 {
ajs2a42e282004-12-08 18:43:03 +00002436 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002437 "dropping.",
2438 ospf_packet_type_str[ospfh->type],
2439 inet_ntoa (iph->ip_src));
2440 }
paul718e3742002-12-13 20:15:29 +00002441 return ret;
2442 }
2443
paul9985f832005-02-09 15:51:56 +00002444 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002445
2446 /* Adjust size to message length. */
2447 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2448
2449 /* Read rest of the packet and call each sort of packet routine. */
2450 switch (ospfh->type)
2451 {
2452 case OSPF_MSG_HELLO:
2453 ospf_hello (iph, ospfh, ibuf, oi, length);
2454 break;
2455 case OSPF_MSG_DB_DESC:
2456 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2457 break;
2458 case OSPF_MSG_LS_REQ:
2459 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2460 break;
2461 case OSPF_MSG_LS_UPD:
2462 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2463 break;
2464 case OSPF_MSG_LS_ACK:
2465 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2466 break;
2467 default:
2468 zlog (NULL, LOG_WARNING,
2469 "interface %s: OSPF packet header type %d is illegal",
2470 IF_NAME (oi), ospfh->type);
2471 break;
2472 }
2473
paul718e3742002-12-13 20:15:29 +00002474 return 0;
2475}
2476
2477/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002478static void
paul718e3742002-12-13 20:15:29 +00002479ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2480{
2481 struct ospf_header *ospfh;
2482
2483 ospfh = (struct ospf_header *) STREAM_DATA (s);
2484
2485 ospfh->version = (u_char) OSPF_VERSION;
2486 ospfh->type = (u_char) type;
2487
paul68980082003-03-25 05:07:42 +00002488 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002489
2490 ospfh->checksum = 0;
2491 ospfh->area_id = oi->area->area_id;
2492 ospfh->auth_type = htons (ospf_auth_type (oi));
2493
2494 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2495
paul9985f832005-02-09 15:51:56 +00002496 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002497}
2498
2499/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002500static int
paul718e3742002-12-13 20:15:29 +00002501ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2502{
2503 struct crypt_key *ck;
2504
2505 switch (ospf_auth_type (oi))
2506 {
2507 case OSPF_AUTH_NULL:
2508 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2509 break;
2510 case OSPF_AUTH_SIMPLE:
2511 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2512 OSPF_AUTH_SIMPLE_SIZE);
2513 break;
2514 case OSPF_AUTH_CRYPTOGRAPHIC:
2515 /* If key is not set, then set 0. */
2516 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2517 {
2518 ospfh->u.crypt.zero = 0;
2519 ospfh->u.crypt.key_id = 0;
2520 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2521 }
2522 else
2523 {
paul1eb8ef22005-04-07 07:30:20 +00002524 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002525 ospfh->u.crypt.zero = 0;
2526 ospfh->u.crypt.key_id = ck->key_id;
2527 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2528 }
2529 /* note: the seq is done in ospf_make_md5_digest() */
2530 break;
2531 default:
2532 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2533 break;
2534 }
2535
2536 return 0;
2537}
2538
2539/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002540static void
paul718e3742002-12-13 20:15:29 +00002541ospf_fill_header (struct ospf_interface *oi,
2542 struct stream *s, u_int16_t length)
2543{
2544 struct ospf_header *ospfh;
2545
2546 ospfh = (struct ospf_header *) STREAM_DATA (s);
2547
2548 /* Fill length. */
2549 ospfh->length = htons (length);
2550
2551 /* Calculate checksum. */
2552 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2553 ospfh->checksum = in_cksum (ospfh, length);
2554 else
2555 ospfh->checksum = 0;
2556
2557 /* Add Authentication Data. */
2558 ospf_make_auth (oi, ospfh);
2559}
2560
paul4dadc292005-05-06 21:37:42 +00002561static int
paul718e3742002-12-13 20:15:29 +00002562ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2563{
2564 struct ospf_neighbor *nbr;
2565 struct route_node *rn;
2566 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2567 struct in_addr mask;
2568 unsigned long p;
2569 int flag = 0;
2570
2571 /* Set netmask of interface. */
2572 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2573 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2574 masklen2ip (oi->address->prefixlen, &mask);
2575 else
2576 memset ((char *) &mask, 0, sizeof (struct in_addr));
2577 stream_put_ipv4 (s, mask.s_addr);
2578
2579 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002580 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2581 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2582 else
2583 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002584
2585 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002586 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002587 OPTIONS(oi), IF_NAME (oi));
2588
2589 /* Set Options. */
2590 stream_putc (s, OPTIONS (oi));
2591
2592 /* Set Router Priority. */
2593 stream_putc (s, PRIORITY (oi));
2594
2595 /* Set Router Dead Interval. */
2596 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2597
2598 /* Set Designated Router. */
2599 stream_put_ipv4 (s, DR (oi).s_addr);
2600
paul9985f832005-02-09 15:51:56 +00002601 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002602
2603 /* Set Backup Designated Router. */
2604 stream_put_ipv4 (s, BDR (oi).s_addr);
2605
2606 /* Add neighbor seen. */
2607 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002608 if ((nbr = rn->info))
2609 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2610 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2611 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2612 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002613 {
2614 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002615 if (nbr->d_router.s_addr != 0
2616 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2617 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2618 flag = 1;
paul718e3742002-12-13 20:15:29 +00002619
2620 stream_put_ipv4 (s, nbr->router_id.s_addr);
2621 length += 4;
2622 }
2623
2624 /* Let neighbor generate BackupSeen. */
2625 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002626 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002627
2628 return length;
2629}
2630
paul4dadc292005-05-06 21:37:42 +00002631static int
paul718e3742002-12-13 20:15:29 +00002632ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2633 struct stream *s)
2634{
2635 struct ospf_lsa *lsa;
2636 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2637 u_char options;
2638 unsigned long pp;
2639 int i;
2640 struct ospf_lsdb *lsdb;
2641
2642 /* Set Interface MTU. */
2643 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2644 stream_putw (s, 0);
2645 else
2646 stream_putw (s, oi->ifp->mtu);
2647
2648 /* Set Options. */
2649 options = OPTIONS (oi);
2650#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002651 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002652 {
2653 if (IS_SET_DD_I (nbr->dd_flags)
2654 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2655 /*
2656 * Set O-bit in the outgoing DD packet for capablity negotiation,
2657 * if one of following case is applicable.
2658 *
2659 * 1) WaitTimer expiration event triggered the neighbor state to
2660 * change to Exstart, but no (valid) DD packet has received
2661 * from the neighbor yet.
2662 *
2663 * 2) At least one DD packet with O-bit on has received from the
2664 * neighbor.
2665 */
2666 SET_FLAG (options, OSPF_OPTION_O);
2667 }
2668#endif /* HAVE_OPAQUE_LSA */
2669 stream_putc (s, options);
2670
2671 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002672 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002673 stream_putc (s, nbr->dd_flags);
2674
2675 /* Set DD Sequence Number. */
2676 stream_putl (s, nbr->dd_seqnum);
2677
2678 if (ospf_db_summary_isempty (nbr))
2679 {
2680 if (nbr->state >= NSM_Exchange)
2681 {
2682 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2683 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002684 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002685 }
2686 return length;
2687 }
2688
2689 /* Describe LSA Header from Database Summary List. */
2690 lsdb = &nbr->db_sum;
2691
2692 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2693 {
2694 struct route_table *table = lsdb->type[i].db;
2695 struct route_node *rn;
2696
2697 for (rn = route_top (table); rn; rn = route_next (rn))
2698 if ((lsa = rn->info) != NULL)
2699 {
2700#ifdef HAVE_OPAQUE_LSA
2701 if (IS_OPAQUE_LSA (lsa->data->type)
2702 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2703 {
2704 /* Suppress advertising opaque-informations. */
2705 /* Remove LSA from DB summary list. */
2706 ospf_lsdb_delete (lsdb, lsa);
2707 continue;
2708 }
2709#endif /* HAVE_OPAQUE_LSA */
2710
2711 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2712 {
2713 struct lsa_header *lsah;
2714 u_int16_t ls_age;
2715
2716 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002717 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002718 break;
2719
2720 /* Keep pointer to LS age. */
2721 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002722 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002723
2724 /* Proceed stream pointer. */
2725 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2726 length += OSPF_LSA_HEADER_SIZE;
2727
2728 /* Set LS age. */
2729 ls_age = LS_AGE (lsa);
2730 lsah->ls_age = htons (ls_age);
2731
2732 }
2733
2734 /* Remove LSA from DB summary list. */
2735 ospf_lsdb_delete (lsdb, lsa);
2736 }
2737 }
2738
2739 return length;
2740}
2741
paul4dadc292005-05-06 21:37:42 +00002742static int
paul718e3742002-12-13 20:15:29 +00002743ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2744 unsigned long delta, struct ospf_neighbor *nbr,
2745 struct ospf_lsa *lsa)
2746{
2747 struct ospf_interface *oi;
2748
2749 oi = nbr->oi;
2750
2751 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002752 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002753 return 0;
2754
2755 stream_putl (s, lsa->data->type);
2756 stream_put_ipv4 (s, lsa->data->id.s_addr);
2757 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2758
2759 ospf_lsa_unlock (nbr->ls_req_last);
2760 nbr->ls_req_last = ospf_lsa_lock (lsa);
2761
2762 *length += 12;
2763 return 1;
2764}
2765
paul4dadc292005-05-06 21:37:42 +00002766static int
paul718e3742002-12-13 20:15:29 +00002767ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2768{
2769 struct ospf_lsa *lsa;
2770 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002771 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002772 struct route_table *table;
2773 struct route_node *rn;
2774 int i;
2775 struct ospf_lsdb *lsdb;
2776
2777 lsdb = &nbr->ls_req;
2778
2779 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2780 {
2781 table = lsdb->type[i].db;
2782 for (rn = route_top (table); rn; rn = route_next (rn))
2783 if ((lsa = (rn->info)) != NULL)
2784 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2785 {
2786 route_unlock_node (rn);
2787 break;
2788 }
2789 }
2790 return length;
2791}
2792
paul4dadc292005-05-06 21:37:42 +00002793static int
paul718e3742002-12-13 20:15:29 +00002794ls_age_increment (struct ospf_lsa *lsa, int delay)
2795{
2796 int age;
2797
2798 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2799
2800 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2801}
2802
paul4dadc292005-05-06 21:37:42 +00002803static int
hasso52dc7ee2004-09-23 19:18:23 +00002804ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002805{
2806 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002807 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002808 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002809 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002810 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002811 unsigned long pp;
2812 int count = 0;
2813
2814 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002815 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002816
paul9985f832005-02-09 15:51:56 +00002817 pp = stream_get_endp (s);
2818 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002819
gdt86f1fd92005-01-10 14:20:43 +00002820 /* Calculate amount of packet usable for data. */
2821 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2822
paul718e3742002-12-13 20:15:29 +00002823 while ((node = listhead (update)) != NULL)
2824 {
2825 struct lsa_header *lsah;
2826 u_int16_t ls_age;
2827
2828 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002829 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002830
paul1eb8ef22005-04-07 07:30:20 +00002831 lsa = listgetdata (node);
2832
paul718e3742002-12-13 20:15:29 +00002833 assert (lsa->data);
2834
paul68b73392004-09-12 14:21:37 +00002835 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002836 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002837 break;
2838
paul718e3742002-12-13 20:15:29 +00002839 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002840 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002841
2842 /* Put LSA to Link State Request. */
2843 stream_put (s, lsa->data, ntohs (lsa->data->length));
2844
2845 /* Set LS age. */
2846 /* each hop must increment an lsa_age by transmit_delay
2847 of OSPF interface */
2848 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2849 lsah->ls_age = htons (ls_age);
2850
2851 length += ntohs (lsa->data->length);
2852 count++;
2853
2854 list_delete_node (update, node);
2855 ospf_lsa_unlock (lsa);
2856 }
2857
2858 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002859 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002860
2861 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002862 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002863 return length;
2864}
2865
paul4dadc292005-05-06 21:37:42 +00002866static int
hasso52dc7ee2004-09-23 19:18:23 +00002867ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002868{
hasso52dc7ee2004-09-23 19:18:23 +00002869 struct list *rm_list;
2870 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002871 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002872 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002873 struct ospf_lsa *lsa;
2874
2875 rm_list = list_new ();
2876
paul1eb8ef22005-04-07 07:30:20 +00002877 for (ALL_LIST_ELEMENTS_RO (ack, node, lsa))
paul718e3742002-12-13 20:15:29 +00002878 {
paul1eb8ef22005-04-07 07:30:20 +00002879 lsa = listgetdata (node);
paul718e3742002-12-13 20:15:29 +00002880 assert (lsa);
2881
gdt86f1fd92005-01-10 14:20:43 +00002882 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002883 break;
2884
2885 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2886 length += OSPF_LSA_HEADER_SIZE;
2887
2888 listnode_add (rm_list, lsa);
2889 }
2890
2891 /* Remove LSA from LS-Ack list. */
paul1eb8ef22005-04-07 07:30:20 +00002892 /* XXX: this loop should be removed and the list move done in previous
2893 * loop
2894 */
2895 for (ALL_LIST_ELEMENTS_RO (rm_list, node, lsa))
paul718e3742002-12-13 20:15:29 +00002896 {
paul718e3742002-12-13 20:15:29 +00002897 listnode_delete (ack, lsa);
2898 ospf_lsa_unlock (lsa);
2899 }
2900
2901 list_delete (rm_list);
2902
2903 return length;
2904}
2905
2906void
2907ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2908{
2909 struct ospf_packet *op;
2910 u_int16_t length = OSPF_HEADER_SIZE;
2911
2912 op = ospf_packet_new (oi->ifp->mtu);
2913
2914 /* Prepare OSPF common header. */
2915 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2916
2917 /* Prepare OSPF Hello body. */
2918 length += ospf_make_hello (oi, op->s);
2919
2920 /* Fill OSPF header. */
2921 ospf_fill_header (oi, op->s, length);
2922
2923 /* Set packet length. */
2924 op->length = length;
2925
2926 op->dst.s_addr = addr->s_addr;
2927
2928 /* Add packet to the interface output queue. */
2929 ospf_packet_add (oi, op);
2930
2931 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002932 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002933}
2934
paul4dadc292005-05-06 21:37:42 +00002935static void
paul718e3742002-12-13 20:15:29 +00002936ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2937{
2938 struct ospf_interface *oi;
2939
2940 oi = nbr_nbma->oi;
2941 assert(oi);
2942
2943 /* If this is passive interface, do not send OSPF Hello. */
2944 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2945 return;
2946
2947 if (oi->type != OSPF_IFTYPE_NBMA)
2948 return;
2949
2950 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2951 return;
2952
2953 if (PRIORITY(oi) == 0)
2954 return;
2955
2956 if (nbr_nbma->priority == 0
2957 && oi->state != ISM_DR && oi->state != ISM_Backup)
2958 return;
2959
2960 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2961}
2962
2963int
2964ospf_poll_timer (struct thread *thread)
2965{
2966 struct ospf_nbr_nbma *nbr_nbma;
2967
2968 nbr_nbma = THREAD_ARG (thread);
2969 nbr_nbma->t_poll = NULL;
2970
2971 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002972 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002973 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2974
2975 ospf_poll_send (nbr_nbma);
2976
2977 if (nbr_nbma->v_poll > 0)
2978 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2979 nbr_nbma->v_poll);
2980
2981 return 0;
2982}
2983
2984
2985int
2986ospf_hello_reply_timer (struct thread *thread)
2987{
2988 struct ospf_neighbor *nbr;
2989
2990 nbr = THREAD_ARG (thread);
2991 nbr->t_hello_reply = NULL;
2992
2993 assert (nbr->oi);
2994
2995 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002996 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00002997 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2998
2999 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3000
3001 return 0;
3002}
3003
3004/* Send OSPF Hello. */
3005void
3006ospf_hello_send (struct ospf_interface *oi)
3007{
3008 struct ospf_packet *op;
3009 u_int16_t length = OSPF_HEADER_SIZE;
3010
3011 /* If this is passive interface, do not send OSPF Hello. */
3012 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3013 return;
3014
3015 op = ospf_packet_new (oi->ifp->mtu);
3016
3017 /* Prepare OSPF common header. */
3018 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3019
3020 /* Prepare OSPF Hello body. */
3021 length += ospf_make_hello (oi, op->s);
3022
3023 /* Fill OSPF header. */
3024 ospf_fill_header (oi, op->s, length);
3025
3026 /* Set packet length. */
3027 op->length = length;
3028
3029 if (oi->type == OSPF_IFTYPE_NBMA)
3030 {
3031 struct ospf_neighbor *nbr;
3032 struct route_node *rn;
3033
3034 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3035 if ((nbr = rn->info))
3036 if (nbr != oi->nbr_self)
3037 if (nbr->state != NSM_Down)
3038 {
3039 /* RFC 2328 Section 9.5.1
3040 If the router is not eligible to become Designated Router,
3041 it must periodically send Hello Packets to both the
3042 Designated Router and the Backup Designated Router (if they
3043 exist). */
3044 if (PRIORITY(oi) == 0 &&
3045 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3046 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3047 continue;
3048
3049 /* If the router is eligible to become Designated Router, it
3050 must periodically send Hello Packets to all neighbors that
3051 are also eligible. In addition, if the router is itself the
3052 Designated Router or Backup Designated Router, it must also
3053 send periodic Hello Packets to all other neighbors. */
3054
3055 if (nbr->priority == 0 && oi->state == ISM_DROther)
3056 continue;
3057 /* if oi->state == Waiting, send hello to all neighbors */
3058 {
3059 struct ospf_packet *op_dup;
3060
3061 op_dup = ospf_packet_dup(op);
3062 op_dup->dst = nbr->address.u.prefix4;
3063
3064 /* Add packet to the interface output queue. */
3065 ospf_packet_add (oi, op_dup);
3066
paul020709f2003-04-04 02:44:16 +00003067 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003068 }
3069
3070 }
3071 ospf_packet_free (op);
3072 }
3073 else
3074 {
3075 /* Decide destination address. */
3076 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3077 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3078 else
3079 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3080
3081 /* Add packet to the interface output queue. */
3082 ospf_packet_add (oi, op);
3083
3084 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003085 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003086 }
3087}
3088
3089/* Send OSPF Database Description. */
3090void
3091ospf_db_desc_send (struct ospf_neighbor *nbr)
3092{
3093 struct ospf_interface *oi;
3094 struct ospf_packet *op;
3095 u_int16_t length = OSPF_HEADER_SIZE;
3096
3097 oi = nbr->oi;
3098 op = ospf_packet_new (oi->ifp->mtu);
3099
3100 /* Prepare OSPF common header. */
3101 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3102
3103 /* Prepare OSPF Database Description body. */
3104 length += ospf_make_db_desc (oi, nbr, op->s);
3105
3106 /* Fill OSPF header. */
3107 ospf_fill_header (oi, op->s, length);
3108
3109 /* Set packet length. */
3110 op->length = length;
3111
3112 /* Decide destination address. */
3113 op->dst = nbr->address.u.prefix4;
3114
3115 /* Add packet to the interface output queue. */
3116 ospf_packet_add (oi, op);
3117
3118 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003119 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003120
3121 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3122 if (nbr->last_send)
3123 ospf_packet_free (nbr->last_send);
3124 nbr->last_send = ospf_packet_dup (op);
3125 gettimeofday (&nbr->last_send_ts, NULL);
3126}
3127
3128/* Re-send Database Description. */
3129void
3130ospf_db_desc_resend (struct ospf_neighbor *nbr)
3131{
3132 struct ospf_interface *oi;
3133
3134 oi = nbr->oi;
3135
3136 /* Add packet to the interface output queue. */
3137 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3138
3139 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003140 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003141}
3142
3143/* Send Link State Request. */
3144void
3145ospf_ls_req_send (struct ospf_neighbor *nbr)
3146{
3147 struct ospf_interface *oi;
3148 struct ospf_packet *op;
3149 u_int16_t length = OSPF_HEADER_SIZE;
3150
3151 oi = nbr->oi;
3152 op = ospf_packet_new (oi->ifp->mtu);
3153
3154 /* Prepare OSPF common header. */
3155 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3156
3157 /* Prepare OSPF Link State Request body. */
3158 length += ospf_make_ls_req (nbr, op->s);
3159 if (length == OSPF_HEADER_SIZE)
3160 {
3161 ospf_packet_free (op);
3162 return;
3163 }
3164
3165 /* Fill OSPF header. */
3166 ospf_fill_header (oi, op->s, length);
3167
3168 /* Set packet length. */
3169 op->length = length;
3170
3171 /* Decide destination address. */
3172 op->dst = nbr->address.u.prefix4;
3173
3174 /* Add packet to the interface output queue. */
3175 ospf_packet_add (oi, op);
3176
3177 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003178 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003179
3180 /* Add Link State Request Retransmission Timer. */
3181 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3182}
3183
3184/* Send Link State Update with an LSA. */
3185void
3186ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3187 int flag)
3188{
hasso52dc7ee2004-09-23 19:18:23 +00003189 struct list *update;
paul718e3742002-12-13 20:15:29 +00003190
3191 update = list_new ();
3192
3193 listnode_add (update, lsa);
3194 ospf_ls_upd_send (nbr, update, flag);
3195
3196 list_delete (update);
3197}
3198
paul68b73392004-09-12 14:21:37 +00003199/* Determine size for packet. Must be at least big enough to accomodate next
3200 * LSA on list, which may be bigger than MTU size.
3201 *
3202 * Return pointer to new ospf_packet
3203 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3204 * on packet sizes (in which case offending LSA is deleted from update list)
3205 */
3206static struct ospf_packet *
3207ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3208{
3209 struct ospf_lsa *lsa;
3210 struct listnode *ln;
3211 size_t size;
3212 static char warned = 0;
3213
paul1eb8ef22005-04-07 07:30:20 +00003214 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003215 assert (lsa->data);
3216
3217 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3218 > ospf_packet_max (oi))
3219 {
3220 if (!warned)
3221 {
3222 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3223 "will need to fragment. Not optimal. Try divide up"
3224 " your network with areas. Use 'debug ospf packet send'"
3225 " to see details, or look at 'show ip ospf database ..'");
3226 warned = 1;
3227 }
3228
3229 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003230 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003231 " %d bytes originated by %s, will be fragmented!",
3232 inet_ntoa (lsa->data->id),
3233 ntohs (lsa->data->length),
3234 inet_ntoa (lsa->data->adv_router));
3235
3236 /*
3237 * Allocate just enough to fit this LSA only, to avoid including other
3238 * LSAs in fragmented LSA Updates.
3239 */
3240 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3241 + OSPF_LS_UPD_MIN_SIZE;
3242 }
3243 else
3244 size = oi->ifp->mtu;
3245
gdt86f1fd92005-01-10 14:20:43 +00003246 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003247 if (size > OSPF_MAX_PACKET_SIZE)
3248 {
3249 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003250 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003251 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003252 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003253 (long int) size);
paul68b73392004-09-12 14:21:37 +00003254 list_delete_node (update, ln);
3255 return NULL;
3256 }
3257
3258 return ospf_packet_new (size);
3259}
3260
paul718e3742002-12-13 20:15:29 +00003261static void
hasso52dc7ee2004-09-23 19:18:23 +00003262ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003263 struct in_addr addr)
3264{
3265 struct ospf_packet *op;
3266 u_int16_t length = OSPF_HEADER_SIZE;
3267
3268 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003269 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003270
3271 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003272
3273 /* Prepare OSPF common header. */
3274 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3275
paul59ea14c2004-07-14 20:50:36 +00003276 /* Prepare OSPF Link State Update body.
3277 * Includes Type-7 translation.
3278 */
paul718e3742002-12-13 20:15:29 +00003279 length += ospf_make_ls_upd (oi, update, op->s);
3280
3281 /* Fill OSPF header. */
3282 ospf_fill_header (oi, op->s, length);
3283
3284 /* Set packet length. */
3285 op->length = length;
3286
3287 /* Decide destination address. */
3288 op->dst.s_addr = addr.s_addr;
3289
3290 /* Add packet to the interface output queue. */
3291 ospf_packet_add (oi, op);
3292
3293 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003294 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003295}
3296
3297static int
3298ospf_ls_upd_send_queue_event (struct thread *thread)
3299{
3300 struct ospf_interface *oi = THREAD_ARG(thread);
3301 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003302 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003303 struct list *update;
paul68b73392004-09-12 14:21:37 +00003304 char again = 0;
paul718e3742002-12-13 20:15:29 +00003305
3306 oi->t_ls_upd_event = NULL;
3307
3308 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003309 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003310
paul736d3442003-07-24 23:22:57 +00003311 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003312 {
paul736d3442003-07-24 23:22:57 +00003313 rnext = route_next (rn);
3314
paul718e3742002-12-13 20:15:29 +00003315 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003316 continue;
paul68b73392004-09-12 14:21:37 +00003317
3318 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003319
paul48fe13b2004-07-27 17:40:44 +00003320 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003321
paul68b73392004-09-12 14:21:37 +00003322 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003323 if (listcount(update) == 0)
3324 {
3325 list_delete (rn->info);
3326 rn->info = NULL;
3327 route_unlock_node (rn);
3328 }
3329 else
paul68b73392004-09-12 14:21:37 +00003330 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003331 }
3332
3333 if (again != 0)
3334 {
3335 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003336 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003337 " %d nodes to try again, raising new event", again);
3338 oi->t_ls_upd_event =
3339 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003340 }
3341
3342 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003343 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003344
paul718e3742002-12-13 20:15:29 +00003345 return 0;
3346}
3347
3348void
hasso52dc7ee2004-09-23 19:18:23 +00003349ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003350{
3351 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003352 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003353 struct prefix_ipv4 p;
3354 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003355 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003356
3357 oi = nbr->oi;
3358
3359 p.family = AF_INET;
3360 p.prefixlen = IPV4_MAX_BITLEN;
3361
3362 /* Decide destination address. */
3363 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3364 p.prefix = oi->vl_data->peer_addr;
3365 else if (flag == OSPF_SEND_PACKET_DIRECT)
3366 p.prefix = nbr->address.u.prefix4;
3367 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3368 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3369 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3370 && (flag == OSPF_SEND_PACKET_INDIRECT))
3371 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003372 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3373 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003374 else
3375 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3376
3377 if (oi->type == OSPF_IFTYPE_NBMA)
3378 {
3379 if (flag == OSPF_SEND_PACKET_INDIRECT)
3380 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3381 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3382 zlog_warn ("* LS-Update is sent to myself.");
3383 }
3384
3385 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3386
3387 if (rn->info == NULL)
3388 rn->info = list_new ();
3389
paul1eb8ef22005-04-07 07:30:20 +00003390 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3391 {
3392 ospf_lsa_lock (lsa);
3393 listnode_add (rn->info, lsa);
3394 }
paul718e3742002-12-13 20:15:29 +00003395
3396 if (oi->t_ls_upd_event == NULL)
3397 oi->t_ls_upd_event =
3398 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3399}
3400
3401static void
hasso52dc7ee2004-09-23 19:18:23 +00003402ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3403 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003404{
3405 struct ospf_packet *op;
3406 u_int16_t length = OSPF_HEADER_SIZE;
3407
3408 op = ospf_packet_new (oi->ifp->mtu);
3409
3410 /* Prepare OSPF common header. */
3411 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3412
3413 /* Prepare OSPF Link State Acknowledgment body. */
3414 length += ospf_make_ls_ack (oi, ack, op->s);
3415
3416 /* Fill OSPF header. */
3417 ospf_fill_header (oi, op->s, length);
3418
3419 /* Set packet length. */
3420 op->length = length;
3421
3422 /* Set destination IP address. */
3423 op->dst = dst;
3424
3425 /* Add packet to the interface output queue. */
3426 ospf_packet_add (oi, op);
3427
3428 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003429 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003430}
3431
3432static int
3433ospf_ls_ack_send_event (struct thread *thread)
3434{
3435 struct ospf_interface *oi = THREAD_ARG (thread);
3436
3437 oi->t_ls_ack_direct = NULL;
3438
3439 while (listcount (oi->ls_ack_direct.ls_ack))
3440 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3441 oi->ls_ack_direct.dst);
3442
3443 return 0;
3444}
3445
3446void
3447ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3448{
3449 struct ospf_interface *oi = nbr->oi;
3450
3451 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3452 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3453
3454 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3455
3456 if (oi->t_ls_ack_direct == NULL)
3457 oi->t_ls_ack_direct =
3458 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3459}
3460
3461/* Send Link State Acknowledgment delayed. */
3462void
3463ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3464{
3465 struct in_addr dst;
3466
3467 /* Decide destination address. */
3468 /* RFC2328 Section 13.5 On non-broadcast
3469 networks, delayed Link State Acknowledgment packets must be
3470 unicast separately over each adjacency (i.e., neighbor whose
3471 state is >= Exchange). */
3472 if (oi->type == OSPF_IFTYPE_NBMA)
3473 {
3474 struct ospf_neighbor *nbr;
3475 struct route_node *rn;
3476
3477 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3478 if ((nbr = rn->info) != NULL)
3479 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3480 while (listcount (oi->ls_ack))
3481 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3482 return;
3483 }
3484 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3485 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3486 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3487 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3488 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3489 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003490 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3491 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003492 else
3493 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3494
3495 while (listcount (oi->ls_ack))
3496 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3497}