blob: 8b7c63a93afd94973215d4de45aeb73995396527 [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"
paul484315f2005-11-03 09:08:29 +000035#include "checksum.h"
vincentc1a03d42005-09-28 15:47:44 +000036#include "md5.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "ospfd/ospfd.h"
39#include "ospfd/ospf_network.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_ism.h"
42#include "ospfd/ospf_asbr.h"
43#include "ospfd/ospf_lsa.h"
44#include "ospfd/ospf_lsdb.h"
45#include "ospfd/ospf_neighbor.h"
46#include "ospfd/ospf_nsm.h"
47#include "ospfd/ospf_packet.h"
48#include "ospfd/ospf_spf.h"
49#include "ospfd/ospf_flood.h"
50#include "ospfd/ospf_dump.h"
51
paul718e3742002-12-13 20:15:29 +000052/* Packet Type String. */
hassoeb1ce602004-10-08 08:17:22 +000053const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000054{
55 "unknown",
56 "Hello",
57 "Database Description",
58 "Link State Request",
59 "Link State Update",
60 "Link State Acknowledgment",
61};
62
paul718e3742002-12-13 20:15:29 +000063/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000064static int
paul718e3742002-12-13 20:15:29 +000065ospf_auth_type (struct ospf_interface *oi)
66{
67 int auth_type;
68
69 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
70 auth_type = oi->area->auth_type;
71 else
72 auth_type = OSPF_IF_PARAM (oi, auth_type);
73
74 /* Handle case where MD5 key list is not configured aka Cisco */
75 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
76 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
77 return OSPF_AUTH_NULL;
78
79 return auth_type;
80
81}
82
paul718e3742002-12-13 20:15:29 +000083struct ospf_packet *
84ospf_packet_new (size_t size)
85{
86 struct ospf_packet *new;
87
88 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
89 new->s = stream_new (size);
90
91 return new;
92}
93
94void
95ospf_packet_free (struct ospf_packet *op)
96{
97 if (op->s)
98 stream_free (op->s);
99
100 XFREE (MTYPE_OSPF_PACKET, op);
101
102 op = NULL;
103}
104
105struct ospf_fifo *
106ospf_fifo_new ()
107{
108 struct ospf_fifo *new;
109
110 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
111 return new;
112}
113
114/* Add new packet to fifo. */
115void
116ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
117{
118 if (fifo->tail)
119 fifo->tail->next = op;
120 else
121 fifo->head = op;
122
123 fifo->tail = op;
124
125 fifo->count++;
126}
127
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000128/* Add new packet to head of fifo. */
129static void
130ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
131{
132 op->next = fifo->head;
133
134 if (fifo->tail == NULL)
135 fifo->tail = op;
136
137 fifo->head = op;
138
139 fifo->count++;
140}
141
paul718e3742002-12-13 20:15:29 +0000142/* Delete first packet from fifo. */
143struct ospf_packet *
144ospf_fifo_pop (struct ospf_fifo *fifo)
145{
146 struct ospf_packet *op;
147
148 op = fifo->head;
149
150 if (op)
151 {
152 fifo->head = op->next;
153
154 if (fifo->head == NULL)
155 fifo->tail = NULL;
156
157 fifo->count--;
158 }
159
160 return op;
161}
162
163/* Return first fifo entry. */
164struct ospf_packet *
165ospf_fifo_head (struct ospf_fifo *fifo)
166{
167 return fifo->head;
168}
169
170/* Flush ospf packet fifo. */
171void
172ospf_fifo_flush (struct ospf_fifo *fifo)
173{
174 struct ospf_packet *op;
175 struct ospf_packet *next;
176
177 for (op = fifo->head; op; op = next)
178 {
179 next = op->next;
180 ospf_packet_free (op);
181 }
182 fifo->head = fifo->tail = NULL;
183 fifo->count = 0;
184}
185
186/* Free ospf packet fifo. */
187void
188ospf_fifo_free (struct ospf_fifo *fifo)
189{
190 ospf_fifo_flush (fifo);
191
192 XFREE (MTYPE_OSPF_FIFO, fifo);
193}
194
195void
196ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
197{
ajsc3eab872005-01-29 15:52:07 +0000198 if (!oi->obuf)
199 {
200 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
201 "destination %s) called with NULL obuf, ignoring "
202 "(please report this bug)!\n",
203 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
204 ospf_packet_type_str[stream_getc_from(op->s, 1)],
205 inet_ntoa (op->dst));
206 return;
207 }
208
paul718e3742002-12-13 20:15:29 +0000209 /* Add packet to end of queue. */
210 ospf_fifo_push (oi->obuf, op);
211
212 /* Debug of packet fifo*/
213 /* ospf_fifo_debug (oi->obuf); */
214}
215
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000216static void
217ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
218{
219 if (!oi->obuf)
220 {
221 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
222 "destination %s) called with NULL obuf, ignoring "
223 "(please report this bug)!\n",
224 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
225 ospf_packet_type_str[stream_getc_from(op->s, 1)],
226 inet_ntoa (op->dst));
227 return;
228 }
229
230 /* Add packet to head of queue. */
231 ospf_fifo_push_head (oi->obuf, op);
232
233 /* Debug of packet fifo*/
234 /* ospf_fifo_debug (oi->obuf); */
235}
236
paul718e3742002-12-13 20:15:29 +0000237void
238ospf_packet_delete (struct ospf_interface *oi)
239{
240 struct ospf_packet *op;
241
242 op = ospf_fifo_pop (oi->obuf);
243
244 if (op)
245 ospf_packet_free (op);
246}
247
paul718e3742002-12-13 20:15:29 +0000248struct ospf_packet *
249ospf_packet_dup (struct ospf_packet *op)
250{
251 struct ospf_packet *new;
252
paul37163d62003-02-03 18:40:56 +0000253 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000254 /* XXX size_t */
255 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
256 (u_long)STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000257
258 /* Reserve space for MD5 authentication that may be added later. */
259 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000260 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000261
262 new->dst = op->dst;
263 new->length = op->length;
264
265 return new;
266}
267
gdt86f1fd92005-01-10 14:20:43 +0000268/* XXX inline */
paul4dadc292005-05-06 21:37:42 +0000269static inline unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000270ospf_packet_authspace (struct ospf_interface *oi)
271{
272 int auth = 0;
273
274 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
275 auth = OSPF_AUTH_MD5_SIZE;
276
277 return auth;
278}
279
paul4dadc292005-05-06 21:37:42 +0000280static unsigned int
paul718e3742002-12-13 20:15:29 +0000281ospf_packet_max (struct ospf_interface *oi)
282{
283 int max;
284
gdt86f1fd92005-01-10 14:20:43 +0000285 max = oi->ifp->mtu - ospf_packet_authspace(oi);
286
paul68b73392004-09-12 14:21:37 +0000287 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000288
289 return max;
290}
291
292
paul4dadc292005-05-06 21:37:42 +0000293static int
paul718e3742002-12-13 20:15:29 +0000294ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
295 u_int16_t length)
296{
paul6c835672004-10-11 11:00:30 +0000297 unsigned char *ibuf;
vincentc1a03d42005-09-28 15:47:44 +0000298 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000299 unsigned char digest[OSPF_AUTH_MD5_SIZE];
300 unsigned char *pdigest;
301 struct crypt_key *ck;
302 struct ospf_header *ospfh;
303 struct ospf_neighbor *nbr;
304
305
306 ibuf = STREAM_PNT (s);
307 ospfh = (struct ospf_header *) ibuf;
308
309 /* Get pointer to the end of the packet. */
310 pdigest = ibuf + length;
311
312 /* Get secret key. */
313 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
314 ospfh->u.crypt.key_id);
315 if (ck == NULL)
316 {
317 zlog_warn ("interface %s: ospf_check_md5 no key %d",
318 IF_NAME (oi), ospfh->u.crypt.key_id);
319 return 0;
320 }
321
322 /* check crypto seqnum. */
323 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
324
325 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
326 {
327 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
328 IF_NAME (oi),
329 ntohl(ospfh->u.crypt.crypt_seqnum),
330 ntohl(nbr->crypt_seqnum));
331 return 0;
332 }
333
334 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000335 memset(&ctx, 0, sizeof(ctx));
336 MD5Init(&ctx);
337 MD5Update(&ctx, ibuf, length);
338 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
339 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000340
341 /* compare the two */
342 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
343 {
344 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
345 IF_NAME (oi));
346 return 0;
347 }
348
349 /* save neighbor's crypt_seqnum */
350 if (nbr)
351 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
352 return 1;
353}
354
355/* This function is called from ospf_write(), it will detect the
356 authentication scheme and if it is MD5, it will change the sequence
357 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000358static int
paul718e3742002-12-13 20:15:29 +0000359ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
360{
361 struct ospf_header *ospfh;
362 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000363 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000364 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000365 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000366 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000367 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000368
369 ibuf = STREAM_DATA (op->s);
370 ospfh = (struct ospf_header *) ibuf;
371
372 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
373 return 0;
374
375 /* We do this here so when we dup a packet, we don't have to
Paul Jakma2518efd2006-08-27 06:49:29 +0000376 waste CPU rewriting other headers.
377
378 Note that quagga_time /deliberately/ is not used here */
paul9483e152002-12-13 20:55:25 +0000379 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000380 if (t > oi->crypt_seqnum)
381 oi->crypt_seqnum = t;
382 else
383 oi->crypt_seqnum++;
384
paul9483e152002-12-13 20:55:25 +0000385 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000386
387 /* Get MD5 Authentication key from auth_key list. */
388 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000389 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000390 else
391 {
paul1eb8ef22005-04-07 07:30:20 +0000392 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000393 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000394 }
395
396 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000397 memset(&ctx, 0, sizeof(ctx));
398 MD5Init(&ctx);
399 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
400 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
401 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000402
403 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000404 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000405
406 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000407 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
408
paul37163d62003-02-03 18:40:56 +0000409 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000410 /* XXX size_t */
411 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
412 (u_long)stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000413
414 return OSPF_AUTH_MD5_SIZE;
415}
416
417
paul4dadc292005-05-06 21:37:42 +0000418static int
paul718e3742002-12-13 20:15:29 +0000419ospf_ls_req_timer (struct thread *thread)
420{
421 struct ospf_neighbor *nbr;
422
423 nbr = THREAD_ARG (thread);
424 nbr->t_ls_req = NULL;
425
426 /* Send Link State Request. */
427 if (ospf_ls_request_count (nbr))
428 ospf_ls_req_send (nbr);
429
430 /* Set Link State Request retransmission timer. */
431 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
432
433 return 0;
434}
435
436void
437ospf_ls_req_event (struct ospf_neighbor *nbr)
438{
439 if (nbr->t_ls_req)
440 {
441 thread_cancel (nbr->t_ls_req);
442 nbr->t_ls_req = NULL;
443 }
444 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
445}
446
447/* Cyclic timer function. Fist registered in ospf_nbr_new () in
448 ospf_neighbor.c */
449int
450ospf_ls_upd_timer (struct thread *thread)
451{
452 struct ospf_neighbor *nbr;
453
454 nbr = THREAD_ARG (thread);
455 nbr->t_ls_upd = NULL;
456
457 /* Send Link State Update. */
458 if (ospf_ls_retransmit_count (nbr) > 0)
459 {
hasso52dc7ee2004-09-23 19:18:23 +0000460 struct list *update;
paul718e3742002-12-13 20:15:29 +0000461 struct ospf_lsdb *lsdb;
462 int i;
paul718e3742002-12-13 20:15:29 +0000463 int retransmit_interval;
464
paul718e3742002-12-13 20:15:29 +0000465 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
466
467 lsdb = &nbr->ls_rxmt;
468 update = list_new ();
469
470 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
471 {
472 struct route_table *table = lsdb->type[i].db;
473 struct route_node *rn;
474
475 for (rn = route_top (table); rn; rn = route_next (rn))
476 {
477 struct ospf_lsa *lsa;
478
479 if ((lsa = rn->info) != NULL)
480 /* Don't retransmit an LSA if we received it within
481 the last RxmtInterval seconds - this is to allow the
482 neighbour a chance to acknowledge the LSA as it may
483 have ben just received before the retransmit timer
484 fired. This is a small tweak to what is in the RFC,
485 but it will cut out out a lot of retransmit traffic
486 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000487 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000488 int2tv (retransmit_interval)) >= 0)
489 listnode_add (update, rn->info);
490 }
491 }
492
493 if (listcount (update) > 0)
494 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
495 list_delete (update);
496 }
497
498 /* Set LS Update retransmission timer. */
499 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
500
501 return 0;
502}
503
504int
505ospf_ls_ack_timer (struct thread *thread)
506{
507 struct ospf_interface *oi;
508
509 oi = THREAD_ARG (thread);
510 oi->t_ls_ack = NULL;
511
512 /* Send Link State Acknowledgment. */
513 if (listcount (oi->ls_ack) > 0)
514 ospf_ls_ack_send_delayed (oi);
515
516 /* Set LS Ack timer. */
517 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
518
519 return 0;
520}
521
paul0bfeca32004-09-24 08:07:54 +0000522#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000523static void
paul6a99f832004-09-27 12:56:30 +0000524ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000525 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000526 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000527{
528#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000529 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000530 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000531 int ret;
paul0bfeca32004-09-24 08:07:54 +0000532
533 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000534 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000535
536 /* we can but try.
537 *
538 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
539 * well as the IP_MF flag, making this all quite pointless.
540 *
541 * However, for a system on which IP_MF is left alone, and ip_id left
542 * alone or else which sets same ip_id for each fragment this might
543 * work, eg linux.
544 *
545 * XXX-TODO: It would be much nicer to have the kernel's use their
546 * existing fragmentation support to do this for us. Bugs/RFEs need to
547 * be raised against the various kernels.
548 */
549
550 /* set More Frag */
551 iph->ip_off |= IP_MF;
552
553 /* ip frag offset is expressed in units of 8byte words */
554 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
555
paul62d8e962004-11-02 20:26:45 +0000556 iovp = &msg->msg_iov[1];
557
paul0bfeca32004-09-24 08:07:54 +0000558 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
559 > maxdatasize )
560 {
561 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000562 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
563 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000564 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000565
paul18b12c32004-10-05 14:38:29 +0000566 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000567
paul6a99f832004-09-27 12:56:30 +0000568 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000569
paul18b12c32004-10-05 14:38:29 +0000570 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000571
572 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000573 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000574 " id %d, off %d, len %d, mtu %u failed with %s",
575 inet_ntoa (iph->ip_dst),
576 iph->ip_id,
577 iph->ip_off,
578 iph->ip_len,
579 mtu,
580 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000581
paul37ccfa32004-10-31 11:24:51 +0000582 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
583 {
ajs2a42e282004-12-08 18:43:03 +0000584 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000585 iph->ip_id, iph->ip_off, iph->ip_len,
586 inet_ntoa (iph->ip_dst));
587 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
588 {
ajs2a42e282004-12-08 18:43:03 +0000589 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000590 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000591 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000592 }
593 }
594
paul0bfeca32004-09-24 08:07:54 +0000595 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000596 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000597 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000598 }
599
600 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000601 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
602 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000603 iph->ip_off &= (~IP_MF);
604}
605#endif /* WANT_OSPF_WRITE_FRAGMENT */
606
ajs5dcbdf82005-03-29 16:13:49 +0000607static int
paul718e3742002-12-13 20:15:29 +0000608ospf_write (struct thread *thread)
609{
paul68980082003-03-25 05:07:42 +0000610 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000611 struct ospf_interface *oi;
612 struct ospf_packet *op;
613 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000614 struct ip iph;
615 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000616 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000617 u_char type;
618 int ret;
619 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000620 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000621#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000622 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000623#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000624 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000625#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000626
paul68980082003-03-25 05:07:42 +0000627 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000628
paul68980082003-03-25 05:07:42 +0000629 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000630 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000631 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000632 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000633
634#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000635 /* seed ipid static with low order bits of time */
636 if (ipid == 0)
637 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000638#endif /* WANT_OSPF_WRITE_FRAGMENT */
639
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000640 /* convenience - max OSPF data per packet,
641 * and reliability - not more data, than our
642 * socket can accept
643 */
644 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
645 sizeof (struct ip);
paul68b73392004-09-12 14:21:37 +0000646
paul718e3742002-12-13 20:15:29 +0000647 /* Get one packet from queue. */
648 op = ospf_fifo_head (oi->obuf);
649 assert (op);
650 assert (op->length >= OSPF_HEADER_SIZE);
651
paul68980082003-03-25 05:07:42 +0000652 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
653 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000654 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
655
paul718e3742002-12-13 20:15:29 +0000656 /* Rewrite the md5 signature & update the seq */
657 ospf_make_md5_digest (oi, op);
658
paul37ccfa32004-10-31 11:24:51 +0000659 /* Retrieve OSPF packet type. */
660 stream_set_getp (op->s, 1);
661 type = stream_getc (op->s);
662
paul68b73392004-09-12 14:21:37 +0000663 /* reset get pointer */
664 stream_set_getp (op->s, 0);
665
666 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000667 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000668
paul718e3742002-12-13 20:15:29 +0000669 sa_dst.sin_family = AF_INET;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000670#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +0000671 sa_dst.sin_len = sizeof(sa_dst);
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000672#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +0000673 sa_dst.sin_addr = op->dst;
674 sa_dst.sin_port = htons (0);
675
676 /* Set DONTROUTE flag if dst is unicast. */
677 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
678 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
679 flags = MSG_DONTROUTE;
680
paul68b73392004-09-12 14:21:37 +0000681 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
682 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000683 if ( sizeof (struct ip)
684 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000685 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
686
paul718e3742002-12-13 20:15:29 +0000687 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000688 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000689 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000690
paul0bfeca32004-09-24 08:07:54 +0000691#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000692 /* XXX-MT: not thread-safe at all..
693 * XXX: this presumes this is only programme sending OSPF packets
694 * otherwise, no guarantee ipid will be unique
695 */
696 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000697#endif /* WANT_OSPF_WRITE_FRAGMENT */
698
paul718e3742002-12-13 20:15:29 +0000699 iph.ip_off = 0;
700 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
701 iph.ip_ttl = OSPF_VL_IP_TTL;
702 else
703 iph.ip_ttl = OSPF_IP_TTL;
704 iph.ip_p = IPPROTO_OSPFIGP;
705 iph.ip_sum = 0;
706 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
707 iph.ip_dst.s_addr = op->dst.s_addr;
708
709 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000710 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000711 msg.msg_namelen = sizeof (sa_dst);
712 msg.msg_iov = iov;
713 msg.msg_iovlen = 2;
714 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000715 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
716 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000717 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000718
719 /* Sadly we can not rely on kernels to fragment packets because of either
720 * IP_HDRINCL and/or multicast destination being set.
721 */
paul0bfeca32004-09-24 08:07:54 +0000722#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000723 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000724 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
725 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000726#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000727
728 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000729 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000730 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000731 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000732
733 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000734 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000735 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000736 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000737 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000738
paul718e3742002-12-13 20:15:29 +0000739 /* Show debug sending packet. */
740 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
741 {
742 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
743 {
ajs2a42e282004-12-08 18:43:03 +0000744 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000745 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000746 stream_set_getp (op->s, 0);
747 ospf_packet_dump (op->s);
748 }
749
ajs2a42e282004-12-08 18:43:03 +0000750 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000751 ospf_packet_type_str[type], inet_ntoa (op->dst),
752 IF_NAME (oi));
753
754 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000755 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000756 }
757
758 /* Now delete packet from queue. */
759 ospf_packet_delete (oi);
760
761 if (ospf_fifo_head (oi->obuf) == NULL)
762 {
763 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000764 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000765 }
766
767 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000768 if (!list_isempty (ospf->oi_write_q))
769 ospf->t_write =
770 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000771
772 return 0;
773}
774
775/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000776static void
paul718e3742002-12-13 20:15:29 +0000777ospf_hello (struct ip *iph, struct ospf_header *ospfh,
778 struct stream * s, struct ospf_interface *oi, int size)
779{
780 struct ospf_hello *hello;
781 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000782 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000783 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000784
785 /* increment statistics. */
786 oi->hello_in++;
787
788 hello = (struct ospf_hello *) STREAM_PNT (s);
789
790 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000791 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000792 {
793 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
794 {
ajs2a42e282004-12-08 18:43:03 +0000795 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000796 "dropping.",
797 ospf_packet_type_str[ospfh->type],
798 inet_ntoa (iph->ip_src));
799 }
800 return;
801 }
paul718e3742002-12-13 20:15:29 +0000802
paul718e3742002-12-13 20:15:29 +0000803 /* get neighbor prefix. */
804 p.family = AF_INET;
805 p.prefixlen = ip_masklen (hello->network_mask);
806 p.u.prefix4 = iph->ip_src;
807
808 /* Compare network mask. */
809 /* Checking is ignored for Point-to-Point and Virtual link. */
810 if (oi->type != OSPF_IFTYPE_POINTOPOINT
811 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
812 if (oi->address->prefixlen != p.prefixlen)
813 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000814 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
815 inet_ntoa(ospfh->router_id), IF_NAME(oi),
816 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000817 return;
818 }
819
paul718e3742002-12-13 20:15:29 +0000820 /* Compare Router Dead Interval. */
821 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
822 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000823 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
824 "(expected %u, but received %u).",
825 inet_ntoa(ospfh->router_id),
826 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000827 return;
828 }
829
paulf9ad9372005-10-21 00:45:17 +0000830 /* Compare Hello Interval - ignored if fast-hellos are set. */
831 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
832 {
833 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
834 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000835 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
836 "(expected %u, but received %u).",
837 inet_ntoa(ospfh->router_id),
838 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000839 return;
840 }
841 }
842
paul718e3742002-12-13 20:15:29 +0000843 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000844 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000845 inet_ntoa (ospfh->router_id),
846 ospf_options_dump (hello->options));
847
848 /* Compare options. */
849#define REJECT_IF_TBIT_ON 1 /* XXX */
850#ifdef REJECT_IF_TBIT_ON
851 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
852 {
853 /*
854 * This router does not support non-zero TOS.
855 * Drop this Hello packet not to establish neighbor relationship.
856 */
857 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
858 inet_ntoa (ospfh->router_id));
859 return;
860 }
861#endif /* REJECT_IF_TBIT_ON */
862
863#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000864 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000865 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
866 {
867 /*
868 * This router does know the correct usage of O-bit
869 * the bit should be set in DD packet only.
870 */
871 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
872 inet_ntoa (ospfh->router_id));
873#ifdef STRICT_OBIT_USAGE_CHECK
874 return; /* Reject this packet. */
875#else /* STRICT_OBIT_USAGE_CHECK */
876 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
877#endif /* STRICT_OBIT_USAGE_CHECK */
878 }
879#endif /* HAVE_OPAQUE_LSA */
880
881 /* new for NSSA is to ensure that NP is on and E is off */
882
paul718e3742002-12-13 20:15:29 +0000883 if (oi->area->external_routing == OSPF_AREA_NSSA)
884 {
885 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
886 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
887 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
888 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
889 {
890 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
891 return;
892 }
893 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000894 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000895 }
896 else
paul718e3742002-12-13 20:15:29 +0000897 /* The setting of the E-bit found in the Hello Packet's Options
898 field must match this area's ExternalRoutingCapability A
899 mismatch causes processing to stop and the packet to be
900 dropped. The setting of the rest of the bits in the Hello
901 Packet's Options field should be ignored. */
902 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
903 CHECK_FLAG (hello->options, OSPF_OPTION_E))
904 {
ajs3aa8d5f2004-12-11 18:00:06 +0000905 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
906 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000907 return;
908 }
paul718e3742002-12-13 20:15:29 +0000909
pauld3f0d622004-05-05 15:27:15 +0000910 /* get neighbour struct */
911 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
912
913 /* neighbour must be valid, ospf_nbr_get creates if none existed */
914 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000915
916 old_state = nbr->state;
917
918 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000919 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000920
921 /* RFC2328 Section 9.5.1
922 If the router is not eligible to become Designated Router,
923 (snip) It must also send an Hello Packet in reply to an
924 Hello Packet received from any eligible neighbor (other than
925 the current Designated Router and Backup Designated Router). */
926 if (oi->type == OSPF_IFTYPE_NBMA)
927 if (PRIORITY(oi) == 0 && hello->priority > 0
928 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
929 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
930 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
931 OSPF_HELLO_REPLY_DELAY);
932
933 /* on NBMA network type, it happens to receive bidirectional Hello packet
934 without advance 1-Way Received event.
935 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
936 if (oi->type == OSPF_IFTYPE_NBMA &&
937 (old_state == NSM_Down || old_state == NSM_Attempt))
938 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000939 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000940 nbr->priority = hello->priority;
941 nbr->d_router = hello->d_router;
942 nbr->bd_router = hello->bd_router;
943 return;
944 }
945
paul68980082003-03-25 05:07:42 +0000946 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000947 size - OSPF_HELLO_MIN_SIZE))
948 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000949 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000950 nbr->options |= hello->options;
951 }
952 else
953 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000954 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000955 /* Set neighbor information. */
956 nbr->priority = hello->priority;
957 nbr->d_router = hello->d_router;
958 nbr->bd_router = hello->bd_router;
959 return;
960 }
961
962 /* If neighbor itself declares DR and no BDR exists,
963 cause event BackupSeen */
964 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
965 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
966 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
967
968 /* neighbor itself declares BDR. */
969 if (oi->state == ISM_Waiting &&
970 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
971 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
972
973 /* had not previously. */
974 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
975 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
976 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
977 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
978 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
979
980 /* had not previously. */
981 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
982 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
983 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
984 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
985 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
986
987 /* Neighbor priority check. */
988 if (nbr->priority >= 0 && nbr->priority != hello->priority)
989 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
990
991 /* Set neighbor information. */
992 nbr->priority = hello->priority;
993 nbr->d_router = hello->d_router;
994 nbr->bd_router = hello->bd_router;
995}
996
997/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000998static void
paul718e3742002-12-13 20:15:29 +0000999ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1000 struct ospf_db_desc *dd)
1001{
1002 nbr->last_recv.flags = dd->flags;
1003 nbr->last_recv.options = dd->options;
1004 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1005}
1006
1007/* Process rest of DD packet. */
1008static void
1009ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1010 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1011 u_int16_t size)
1012{
1013 struct ospf_lsa *new, *find;
1014 struct lsa_header *lsah;
1015
paul9985f832005-02-09 15:51:56 +00001016 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001017 for (size -= OSPF_DB_DESC_MIN_SIZE;
1018 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1019 {
1020 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001021 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001022
1023 /* Unknown LS type. */
1024 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1025 {
ajsbec595a2004-11-30 22:38:43 +00001026 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001027 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1028 return;
1029 }
1030
1031#ifdef HAVE_OPAQUE_LSA
1032 if (IS_OPAQUE_LSA (lsah->type)
1033 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1034 {
1035 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1036 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1037 return;
1038 }
1039#endif /* HAVE_OPAQUE_LSA */
1040
1041 switch (lsah->type)
1042 {
1043 case OSPF_AS_EXTERNAL_LSA:
1044#ifdef HAVE_OPAQUE_LSA
1045 case OSPF_OPAQUE_AS_LSA:
1046#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001047 /* Check for stub area. Reject if AS-External from stub but
1048 allow if from NSSA. */
1049 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001050 {
1051 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1052 lsah->type, inet_ntoa (lsah->id),
1053 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1054 "STUB" : "NSSA");
1055 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1056 return;
1057 }
1058 break;
1059 default:
1060 break;
1061 }
1062
1063 /* Create LS-request object. */
1064 new = ospf_ls_request_new (lsah);
1065
1066 /* Lookup received LSA, then add LS request list. */
1067 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001068
1069 /* ospf_lsa_more_recent is fine with NULL pointers */
1070 switch (ospf_lsa_more_recent (find, new))
1071 {
1072 case -1:
1073 /* Neighbour has a more recent LSA, we must request it */
1074 ospf_ls_request_add (nbr, new);
1075 case 0:
1076 /* If we have a copy of this LSA, it's either less recent
1077 * and we're requesting it from neighbour (the case above), or
1078 * it's as recent and we both have same copy (this case).
1079 *
1080 * In neither of these two cases is there any point in
1081 * describing our copy of the LSA to the neighbour in a
1082 * DB-Summary packet, if we're still intending to do so.
1083 *
1084 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1085 * backward compatible optimisation to OSPF DB Exchange /
1086 * DB Description process implemented here.
1087 */
1088 if (find)
1089 ospf_lsdb_delete (&nbr->db_sum, find);
1090 ospf_lsa_discard (new);
1091 break;
1092 default:
1093 /* We have the more recent copy, nothing specific to do:
1094 * - no need to request neighbours stale copy
1095 * - must leave DB summary list copy alone
1096 */
1097 if (IS_DEBUG_OSPF_EVENT)
1098 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1099 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1100 ospf_lsa_discard (new);
1101 }
paul718e3742002-12-13 20:15:29 +00001102 }
1103
1104 /* Master */
1105 if (IS_SET_DD_MS (nbr->dd_flags))
1106 {
1107 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001108
1109 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001110 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1111 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1112 else
paul718e3742002-12-13 20:15:29 +00001113 ospf_db_desc_send (nbr);
1114 }
1115 /* Slave */
1116 else
1117 {
1118 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1119
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001120 /* Send DD packet in reply.
1121 *
1122 * Must be done to acknowledge the Master's DD, regardless of
1123 * whether we have more LSAs ourselves to describe.
1124 *
1125 * This function will clear the 'More' bit, if after this DD
1126 * we have no more LSAs to describe to the master..
1127 */
paul718e3742002-12-13 20:15:29 +00001128 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001129
1130 /* Slave can raise ExchangeDone now, if master is also done */
1131 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1132 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001133 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001134
paul718e3742002-12-13 20:15:29 +00001135 /* Save received neighbor values from DD. */
1136 ospf_db_desc_save_current (nbr, dd);
1137}
1138
paul4dadc292005-05-06 21:37:42 +00001139static int
paul718e3742002-12-13 20:15:29 +00001140ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1141{
1142 /* Is DD duplicated? */
1143 if (dd->options == nbr->last_recv.options &&
1144 dd->flags == nbr->last_recv.flags &&
1145 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1146 return 1;
1147
1148 return 0;
1149}
1150
1151/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001152static void
paul718e3742002-12-13 20:15:29 +00001153ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1154 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1155{
1156 struct ospf_db_desc *dd;
1157 struct ospf_neighbor *nbr;
1158
1159 /* Increment statistics. */
1160 oi->db_desc_in++;
1161
1162 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001163
pauld3f0d622004-05-05 15:27:15 +00001164 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001165 if (nbr == NULL)
1166 {
1167 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1168 inet_ntoa (ospfh->router_id));
1169 return;
1170 }
1171
1172 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001173 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1174 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001175 {
ajs3aa8d5f2004-12-11 18:00:06 +00001176 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1177 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1178 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001179 return;
1180 }
1181
pauld363df22003-06-19 00:26:34 +00001182 /*
1183 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1184 * required. In fact at least JunOS sends DD packets with P bit clear.
1185 * Until proper solution is developped, this hack should help.
1186 *
1187 * Update: According to the RFCs, N bit is specified /only/ for Hello
1188 * options, unfortunately its use in DD options is not specified. Hence some
1189 * implementations follow E-bit semantics and set it in DD options, and some
1190 * treat it as unspecified and hence follow the directive "default for
1191 * options is clear", ie unset.
1192 *
1193 * Reset the flag, as ospfd follows E-bit semantics.
1194 */
1195 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1196 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1197 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1198 {
1199 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001200 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001201 inet_ntoa (nbr->router_id) );
1202 SET_FLAG (dd->options, OSPF_OPTION_NP);
1203 }
pauld363df22003-06-19 00:26:34 +00001204
paul718e3742002-12-13 20:15:29 +00001205#ifdef REJECT_IF_TBIT_ON
1206 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1207 {
1208 /*
1209 * In Hello protocol, optional capability must have checked
1210 * to prevent this T-bit enabled router be my neighbor.
1211 */
1212 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1213 return;
1214 }
1215#endif /* REJECT_IF_TBIT_ON */
1216
1217#ifdef HAVE_OPAQUE_LSA
1218 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001219 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001220 {
1221 /*
1222 * This node is not configured to handle O-bit, for now.
1223 * Clear it to ignore unsupported capability proposed by neighbor.
1224 */
1225 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1226 }
1227#endif /* HAVE_OPAQUE_LSA */
1228
Paul Jakma57c5c652010-01-07 06:12:53 +00001229 /* Add event to thread. */
1230 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1231
paul718e3742002-12-13 20:15:29 +00001232 /* Process DD packet by neighbor status. */
1233 switch (nbr->state)
1234 {
1235 case NSM_Down:
1236 case NSM_Attempt:
1237 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001238 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001239 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001240 LOOKUP (ospf_nsm_state_msg, nbr->state));
1241 break;
1242 case NSM_Init:
1243 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1244 /* If the new state is ExStart, the processing of the current
1245 packet should then continue in this new state by falling
1246 through to case ExStart below. */
1247 if (nbr->state != NSM_ExStart)
1248 break;
1249 case NSM_ExStart:
1250 /* Initial DBD */
1251 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1252 (size == OSPF_DB_DESC_MIN_SIZE))
1253 {
paul68980082003-03-25 05:07:42 +00001254 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001255 {
1256 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001257 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001258 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001259 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001260
1261 /* Reset I/MS */
1262 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001263 }
1264 else
1265 {
1266 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001267 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001268 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001269 break;
1270 }
1271 }
1272 /* Ack from the Slave */
1273 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1274 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001275 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001276 {
ajs17eaa722004-12-29 21:04:48 +00001277 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001278 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001279 /* Reset I, leaving MS */
1280 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001281 }
1282 else
1283 {
ajs3aa8d5f2004-12-11 18:00:06 +00001284 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1285 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001286 break;
1287 }
1288
1289 /* This is where the real Options are saved */
1290 nbr->options = dd->options;
1291
1292#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001293 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001294 {
1295 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001296 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001297 inet_ntoa (nbr->router_id),
1298 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1299
1300 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1301 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1302 {
paul6d452762005-11-03 11:15:44 +00001303 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1304 "Opaque-LSAs cannot be reliably advertised "
1305 "in this network.",
1306 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001307 /* This situation is undesirable, but not a real error. */
1308 }
1309 }
1310#endif /* HAVE_OPAQUE_LSA */
1311
1312 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1313
1314 /* continue processing rest of packet. */
1315 ospf_db_desc_proc (s, oi, nbr, dd, size);
1316 break;
1317 case NSM_Exchange:
1318 if (ospf_db_desc_is_dup (dd, nbr))
1319 {
1320 if (IS_SET_DD_MS (nbr->dd_flags))
1321 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001322 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001323 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001324 else
1325 /* Slave: cause to retransmit the last Database Description. */
1326 {
paul6d452762005-11-03 11:15:44 +00001327 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001328 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001329 ospf_db_desc_resend (nbr);
1330 }
1331 break;
1332 }
1333
1334 /* Otherwise DD packet should be checked. */
1335 /* Check Master/Slave bit mismatch */
1336 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1337 {
ajs3aa8d5f2004-12-11 18:00:06 +00001338 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1339 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001340 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1341 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001342 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001343 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001344 break;
1345 }
1346
1347 /* Check initialize bit is set. */
1348 if (IS_SET_DD_I (dd->flags))
1349 {
paul6d452762005-11-03 11:15:44 +00001350 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001351 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001352 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1353 break;
1354 }
1355
1356 /* Check DD Options. */
1357 if (dd->options != nbr->options)
1358 {
1359#ifdef ORIGINAL_CODING
1360 /* Save the new options for debugging */
1361 nbr->options = dd->options;
1362#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001363 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1364 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001365 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1366 break;
1367 }
1368
1369 /* Check DD sequence number. */
1370 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1371 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1372 (!IS_SET_DD_MS (nbr->dd_flags) &&
1373 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1374 {
ajs3aa8d5f2004-12-11 18:00:06 +00001375 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1376 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001377 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1378 break;
1379 }
1380
1381 /* Continue processing rest of packet. */
1382 ospf_db_desc_proc (s, oi, nbr, dd, size);
1383 break;
1384 case NSM_Loading:
1385 case NSM_Full:
1386 if (ospf_db_desc_is_dup (dd, nbr))
1387 {
1388 if (IS_SET_DD_MS (nbr->dd_flags))
1389 {
1390 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001391 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1392 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001393 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001394 break;
1395 }
1396 else
1397 {
1398 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001399 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001400 t = tv_sub (now, nbr->last_send_ts);
1401 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1402 {
1403 /* In states Loading and Full the slave must resend
1404 its last Database Description packet in response to
1405 duplicate Database Description packets received
1406 from the master. For this reason the slave must
1407 wait RouterDeadInterval seconds before freeing the
1408 last Database Description packet. Reception of a
1409 Database Description packet from the master after
1410 this interval will generate a SeqNumberMismatch
1411 neighbor event. RFC2328 Section 10.8 */
1412 ospf_db_desc_resend (nbr);
1413 break;
1414 }
1415 }
1416 }
1417
1418 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1419 break;
1420 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001421 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1422 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001423 break;
1424 }
1425}
1426
1427#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1428
1429/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001430static void
paul718e3742002-12-13 20:15:29 +00001431ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1432 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1433{
1434 struct ospf_neighbor *nbr;
1435 u_int32_t ls_type;
1436 struct in_addr ls_id;
1437 struct in_addr adv_router;
1438 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001439 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001440 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001441
1442 /* Increment statistics. */
1443 oi->ls_req_in++;
1444
pauld3f0d622004-05-05 15:27:15 +00001445 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001446 if (nbr == NULL)
1447 {
1448 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1449 inet_ntoa (ospfh->router_id));
1450 return;
1451 }
1452
Paul Jakma57c5c652010-01-07 06:12:53 +00001453 /* Add event to thread. */
1454 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1455
paul718e3742002-12-13 20:15:29 +00001456 /* Neighbor State should be Exchange or later. */
1457 if (nbr->state != NSM_Exchange &&
1458 nbr->state != NSM_Loading &&
1459 nbr->state != NSM_Full)
1460 {
ajsbec595a2004-11-30 22:38:43 +00001461 zlog_warn ("Link State Request received from %s: "
1462 "Neighbor state is %s, packet discarded.",
1463 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001464 LOOKUP (ospf_nsm_state_msg, nbr->state));
1465 return;
1466 }
1467
1468 /* Send Link State Update for ALL requested LSAs. */
1469 ls_upd = list_new ();
1470 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1471
1472 while (size >= OSPF_LSA_KEY_SIZE)
1473 {
1474 /* Get one slice of Link State Request. */
1475 ls_type = stream_getl (s);
1476 ls_id.s_addr = stream_get_ipv4 (s);
1477 adv_router.s_addr = stream_get_ipv4 (s);
1478
1479 /* Verify LSA type. */
1480 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1481 {
1482 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1483 list_delete (ls_upd);
1484 return;
1485 }
1486
1487 /* Search proper LSA in LSDB. */
1488 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1489 if (find == NULL)
1490 {
1491 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1492 list_delete (ls_upd);
1493 return;
1494 }
1495
gdt86f1fd92005-01-10 14:20:43 +00001496 /* Packet overflows MTU size, send immediately. */
1497 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001498 {
1499 if (oi->type == OSPF_IFTYPE_NBMA)
1500 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1501 else
1502 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1503
1504 /* Only remove list contents. Keep ls_upd. */
1505 list_delete_all_node (ls_upd);
1506
1507 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1508 }
1509
1510 /* Append LSA to update list. */
1511 listnode_add (ls_upd, find);
1512 length += ntohs (find->data->length);
1513
1514 size -= OSPF_LSA_KEY_SIZE;
1515 }
1516
1517 /* Send rest of Link State Update. */
1518 if (listcount (ls_upd) > 0)
1519 {
1520 if (oi->type == OSPF_IFTYPE_NBMA)
1521 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1522 else
1523 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1524
1525 list_delete (ls_upd);
1526 }
1527 else
1528 list_free (ls_upd);
1529}
1530
1531/* Get the list of LSAs from Link State Update packet.
1532 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001533static struct list *
paul718e3742002-12-13 20:15:29 +00001534ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1535 struct ospf_interface *oi, size_t size)
1536{
1537 u_int16_t count, sum;
1538 u_int32_t length;
1539 struct lsa_header *lsah;
1540 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001541 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001542
1543 lsas = list_new ();
1544
1545 count = stream_getl (s);
1546 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1547
1548 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001549 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001550 {
1551 lsah = (struct lsa_header *) STREAM_PNT (s);
1552 length = ntohs (lsah->length);
1553
1554 if (length > size)
1555 {
1556 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1557 break;
1558 }
1559
1560 /* Validate the LSA's LS checksum. */
1561 sum = lsah->checksum;
1562 if (sum != ospf_lsa_checksum (lsah))
1563 {
1564 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1565 sum, lsah->checksum);
1566 continue;
1567 }
1568
1569 /* Examine the LSA's LS type. */
1570 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1571 {
1572 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1573 continue;
1574 }
1575
1576 /*
1577 * What if the received LSA's age is greater than MaxAge?
1578 * Treat it as a MaxAge case -- endo.
1579 */
1580 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1581 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1582
1583#ifdef HAVE_OPAQUE_LSA
1584 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1585 {
1586#ifdef STRICT_OBIT_USAGE_CHECK
1587 if ((IS_OPAQUE_LSA(lsah->type) &&
1588 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1589 || (! IS_OPAQUE_LSA(lsah->type) &&
1590 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1591 {
1592 /*
1593 * This neighbor must know the exact usage of O-bit;
1594 * the bit will be set in Type-9,10,11 LSAs only.
1595 */
1596 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1597 continue;
1598 }
1599#endif /* STRICT_OBIT_USAGE_CHECK */
1600
1601 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1602 if (lsah->type == OSPF_OPAQUE_AS_LSA
1603 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1604 {
1605 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001606 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 +00001607 continue;
1608 }
1609 }
1610 else if (IS_OPAQUE_LSA(lsah->type))
1611 {
1612 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1613 continue;
1614 }
1615#endif /* HAVE_OPAQUE_LSA */
1616
1617 /* Create OSPF LSA instance. */
1618 lsa = ospf_lsa_new ();
1619
1620 /* We may wish to put some error checking if type NSSA comes in
1621 and area not in NSSA mode */
1622 switch (lsah->type)
1623 {
1624 case OSPF_AS_EXTERNAL_LSA:
1625#ifdef HAVE_OPAQUE_LSA
1626 case OSPF_OPAQUE_AS_LSA:
1627 lsa->area = NULL;
1628 break;
1629 case OSPF_OPAQUE_LINK_LSA:
1630 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1631 /* Fallthrough */
1632#endif /* HAVE_OPAQUE_LSA */
1633 default:
1634 lsa->area = oi->area;
1635 break;
1636 }
1637
1638 lsa->data = ospf_lsa_data_new (length);
1639 memcpy (lsa->data, lsah, length);
1640
1641 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001642 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001643 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1644 listnode_add (lsas, lsa);
1645 }
1646
1647 return lsas;
1648}
1649
1650/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001651static void
hasso52dc7ee2004-09-23 19:18:23 +00001652ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001653{
paul1eb8ef22005-04-07 07:30:20 +00001654 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001655 struct ospf_lsa *lsa;
1656
paul1eb8ef22005-04-07 07:30:20 +00001657 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1658 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001659
1660 list_delete (lsas);
1661}
1662
1663/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001664static void
paul718e3742002-12-13 20:15:29 +00001665ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1666 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1667{
1668 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001669 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001670 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001671 struct ospf_lsa *lsa = NULL;
1672 /* unsigned long ls_req_found = 0; */
1673
1674 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1675
1676 /* Increment statistics. */
1677 oi->ls_upd_in++;
1678
1679 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001680 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001681 if (nbr == NULL)
1682 {
1683 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1684 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1685 return;
1686 }
1687
Paul Jakma57c5c652010-01-07 06:12:53 +00001688 /* Add event to thread. */
1689 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1690
paul718e3742002-12-13 20:15:29 +00001691 /* Check neighbor state. */
1692 if (nbr->state < NSM_Exchange)
1693 {
ajs3aa8d5f2004-12-11 18:00:06 +00001694 zlog_warn ("Link State Update: "
1695 "Neighbor[%s] state %s is less than Exchange",
1696 inet_ntoa (ospfh->router_id),
1697 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001698 return;
1699 }
1700
1701 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1702 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1703 * of section 13.
1704 */
1705 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1706
1707#ifdef HAVE_OPAQUE_LSA
1708 /*
paul718e3742002-12-13 20:15:29 +00001709 * If self-originated Opaque-LSAs that have flooded before restart
1710 * are contained in the received LSUpd message, corresponding LSReq
1711 * messages to be sent may have to be modified.
1712 * To eliminate possible race conditions such that flushing and normal
1713 * updating for the same LSA would take place alternately, this trick
1714 * must be done before entering to the loop below.
1715 */
paul69310a62005-05-11 18:09:59 +00001716 /* XXX: Why is this Opaque specific? Either our core code is deficient
1717 * and this should be fixed generally, or Opaque is inventing strawman
1718 * problems */
paul718e3742002-12-13 20:15:29 +00001719 ospf_opaque_adjust_lsreq (nbr, lsas);
1720#endif /* HAVE_OPAQUE_LSA */
1721
1722#define DISCARD_LSA(L,N) {\
1723 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001724 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 +00001725 ospf_lsa_discard (L); \
1726 continue; }
1727
1728 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001729 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001730 {
1731 struct ospf_lsa *ls_ret, *current;
1732 int ret = 1;
1733
paul718e3742002-12-13 20:15:29 +00001734 if (IS_DEBUG_OSPF_NSSA)
1735 {
1736 char buf1[INET_ADDRSTRLEN];
1737 char buf2[INET_ADDRSTRLEN];
1738 char buf3[INET_ADDRSTRLEN];
1739
ajs2a42e282004-12-08 18:43:03 +00001740 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001741 lsa->data->type,
1742 inet_ntop (AF_INET, &ospfh->router_id,
1743 buf1, INET_ADDRSTRLEN),
1744 inet_ntop (AF_INET, &lsa->data->id,
1745 buf2, INET_ADDRSTRLEN),
1746 inet_ntop (AF_INET, &lsa->data->adv_router,
1747 buf3, INET_ADDRSTRLEN));
1748 }
paul718e3742002-12-13 20:15:29 +00001749
1750 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1751
1752 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1753
1754 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1755
1756 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1757
1758 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1759
1760 /* Do take in Type-7's if we are an NSSA */
1761
1762 /* If we are also an ABR, later translate them to a Type-5 packet */
1763
1764 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1765 translate them to a separate Type-5 packet. */
1766
1767 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1768 /* Reject from STUB or NSSA */
1769 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1770 {
paul718e3742002-12-13 20:15:29 +00001771 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001772 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001773 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001774 }
1775
paul718e3742002-12-13 20:15:29 +00001776 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1777 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1778 {
paul718e3742002-12-13 20:15:29 +00001779 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001780 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001781 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001782 }
paul718e3742002-12-13 20:15:29 +00001783
1784 /* Find the LSA in the current database. */
1785
1786 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1787
1788 /* If the LSA's LS age is equal to MaxAge, and there is currently
1789 no instance of the LSA in the router's link state database,
1790 and none of router's neighbors are in states Exchange or Loading,
1791 then take the following actions. */
1792
1793 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001794 (ospf_nbr_count (oi, NSM_Exchange) +
1795 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001796 {
1797 /* Response Link State Acknowledgment. */
1798 ospf_ls_ack_send (nbr, lsa);
1799
1800 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001801 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1802 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001803 DISCARD_LSA (lsa, 3);
1804 }
1805
1806#ifdef HAVE_OPAQUE_LSA
1807 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001808 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001809 {
1810 /*
1811 * Even if initial flushing seems to be completed, there might
1812 * be a case that self-originated LSA with MaxAge still remain
1813 * in the routing domain.
1814 * Just send an LSAck message to cease retransmission.
1815 */
1816 if (IS_LSA_MAXAGE (lsa))
1817 {
1818 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1819 ospf_ls_ack_send (nbr, lsa);
1820 ospf_lsa_discard (lsa);
1821
1822 if (current != NULL && ! IS_LSA_MAXAGE (current))
1823 ospf_opaque_lsa_refresh_schedule (current);
1824 continue;
1825 }
1826
1827 /*
1828 * If an instance of self-originated Opaque-LSA is not found
1829 * in the LSDB, there are some possible cases here.
1830 *
1831 * 1) This node lost opaque-capability after restart.
1832 * 2) Else, a part of opaque-type is no more supported.
1833 * 3) Else, a part of opaque-id is no more supported.
1834 *
1835 * Anyway, it is still this node's responsibility to flush it.
1836 * Otherwise, the LSA instance remains in the routing domain
1837 * until its age reaches to MaxAge.
1838 */
paul69310a62005-05-11 18:09:59 +00001839 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001840 if (current == NULL)
1841 {
1842 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001843 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1844 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001845
1846 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001847
1848 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1849 ospf_ls_ack_send (nbr, lsa);
1850
paul718e3742002-12-13 20:15:29 +00001851 continue;
1852 }
1853 }
1854#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001855
hassocb05eb22004-02-11 21:10:19 +00001856 /* It might be happen that received LSA is self-originated network LSA, but
1857 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1858 * Link State ID is one of the router's own IP interface addresses but whose
1859 * Advertising Router is not equal to the router's own Router ID
1860 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1861 */
1862
1863 if(lsa->data->type == OSPF_NETWORK_LSA)
1864 {
paul1eb8ef22005-04-07 07:30:20 +00001865 struct listnode *oinode, *oinnode;
1866 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001867 int Flag = 0;
1868
paul1eb8ef22005-04-07 07:30:20 +00001869 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001870 {
hassocb05eb22004-02-11 21:10:19 +00001871 if(out_if == NULL)
1872 break;
1873
1874 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1875 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1876 {
1877 if(out_if->network_lsa_self)
1878 {
1879 ospf_lsa_flush_area(lsa,out_if->area);
1880 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001881 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001882 lsa, (int) lsa->data->type);
1883 ospf_lsa_discard (lsa);
1884 Flag = 1;
1885 }
1886 break;
1887 }
1888 }
1889 if(Flag)
1890 continue;
1891 }
paul718e3742002-12-13 20:15:29 +00001892
1893 /* (5) Find the instance of this LSA that is currently contained
1894 in the router's link state database. If there is no
1895 database copy, or the received LSA is more recent than
1896 the database copy the following steps must be performed. */
1897
1898 if (current == NULL ||
1899 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1900 {
1901 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001902 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001903 DISCARD_LSA (lsa, 4);
1904 continue;
1905 }
1906
1907 /* (6) Else, If there is an instance of the LSA on the sending
1908 neighbor's Link state request list, an error has occurred in
1909 the Database Exchange process. In this case, restart the
1910 Database Exchange process by generating the neighbor event
1911 BadLSReq for the sending neighbor and stop processing the
1912 Link State Update packet. */
1913
1914 if (ospf_ls_request_lookup (nbr, lsa))
1915 {
1916 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001917 zlog_warn("LSA[%s] instance exists on Link state request list",
1918 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001919
1920 /* Clean list of LSAs. */
1921 ospf_upd_list_clean (lsas);
1922 /* this lsa is not on lsas list already. */
1923 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001924 return;
1925 }
1926
1927 /* If the received LSA is the same instance as the database copy
1928 (i.e., neither one is more recent) the following two steps
1929 should be performed: */
1930
1931 if (ret == 0)
1932 {
1933 /* If the LSA is listed in the Link state retransmission list
1934 for the receiving adjacency, the router itself is expecting
1935 an acknowledgment for this LSA. The router should treat the
1936 received LSA as an acknowledgment by removing the LSA from
1937 the Link state retransmission list. This is termed an
1938 "implied acknowledgment". */
1939
1940 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1941
1942 if (ls_ret != NULL)
1943 {
1944 ospf_ls_retransmit_delete (nbr, ls_ret);
1945
1946 /* Delayed acknowledgment sent if advertisement received
1947 from Designated Router, otherwise do nothing. */
1948 if (oi->state == ISM_Backup)
1949 if (NBR_IS_DR (nbr))
1950 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1951
1952 DISCARD_LSA (lsa, 5);
1953 }
1954 else
1955 /* Acknowledge the receipt of the LSA by sending a
1956 Link State Acknowledgment packet back out the receiving
1957 interface. */
1958 {
1959 ospf_ls_ack_send (nbr, lsa);
1960 DISCARD_LSA (lsa, 6);
1961 }
1962 }
1963
1964 /* The database copy is more recent. If the database copy
1965 has LS age equal to MaxAge and LS sequence number equal to
1966 MaxSequenceNumber, simply discard the received LSA without
1967 acknowledging it. (In this case, the LSA's LS sequence number is
1968 wrapping, and the MaxSequenceNumber LSA must be completely
1969 flushed before any new LSA instance can be introduced). */
1970
1971 else if (ret > 0) /* Database copy is more recent */
1972 {
1973 if (IS_LSA_MAXAGE (current) &&
1974 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1975 {
1976 DISCARD_LSA (lsa, 7);
1977 }
1978 /* Otherwise, as long as the database copy has not been sent in a
1979 Link State Update within the last MinLSArrival seconds, send the
1980 database copy back to the sending neighbor, encapsulated within
1981 a Link State Update Packet. The Link State Update Packet should
1982 be sent directly to the neighbor. In so doing, do not put the
1983 database copy of the LSA on the neighbor's link state
1984 retransmission list, and do not acknowledge the received (less
1985 recent) LSA instance. */
1986 else
1987 {
1988 struct timeval now;
1989
Paul Jakma2518efd2006-08-27 06:49:29 +00001990 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001991
1992 if (tv_cmp (tv_sub (now, current->tv_orig),
Paul Jakma2c9f8e32010-01-11 16:22:12 +00001993 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
paul718e3742002-12-13 20:15:29 +00001994 /* Trap NSSA type later.*/
1995 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1996 DISCARD_LSA (lsa, 8);
1997 }
1998 }
1999 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002000#undef DISCARD_LSA
2001
paul718e3742002-12-13 20:15:29 +00002002 assert (listcount (lsas) == 0);
2003 list_delete (lsas);
2004}
2005
2006/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002007static void
paul718e3742002-12-13 20:15:29 +00002008ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2009 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2010{
2011 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002012
paul718e3742002-12-13 20:15:29 +00002013 /* increment statistics. */
2014 oi->ls_ack_in++;
2015
pauld3f0d622004-05-05 15:27:15 +00002016 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002017 if (nbr == NULL)
2018 {
2019 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2020 inet_ntoa (ospfh->router_id));
2021 return;
2022 }
2023
Paul Jakma57c5c652010-01-07 06:12:53 +00002024 /* Add event to thread. */
2025 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2026
paul718e3742002-12-13 20:15:29 +00002027 if (nbr->state < NSM_Exchange)
2028 {
ajs3aa8d5f2004-12-11 18:00:06 +00002029 zlog_warn ("Link State Acknowledgment: "
2030 "Neighbor[%s] state %s is less than Exchange",
2031 inet_ntoa (ospfh->router_id),
2032 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002033 return;
2034 }
paul69310a62005-05-11 18:09:59 +00002035
paul718e3742002-12-13 20:15:29 +00002036 while (size >= OSPF_LSA_HEADER_SIZE)
2037 {
2038 struct ospf_lsa *lsa, *lsr;
2039
2040 lsa = ospf_lsa_new ();
2041 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2042
2043 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2044 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002045 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002046
2047 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2048 {
2049 lsa->data = NULL;
2050 ospf_lsa_discard (lsa);
2051 continue;
2052 }
2053
2054 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2055
2056 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2057 {
2058#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002059 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002060 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002061#endif /* HAVE_OPAQUE_LSA */
2062
2063 ospf_ls_retransmit_delete (nbr, lsr);
2064 }
2065
2066 lsa->data = NULL;
2067 ospf_lsa_discard (lsa);
2068 }
2069
paul718e3742002-12-13 20:15:29 +00002070 return;
paul718e3742002-12-13 20:15:29 +00002071}
2072
ajs038163f2005-02-17 19:55:59 +00002073static struct stream *
ajs5c333492005-02-23 15:43:01 +00002074ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002075{
2076 int ret;
ajs5c333492005-02-23 15:43:01 +00002077 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002078 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002079 unsigned int ifindex = 0;
2080 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002081 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002082 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002083 struct msghdr msgh;
2084
paul68defd62004-09-27 07:27:13 +00002085 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002086 msgh.msg_iov = &iov;
2087 msgh.msg_iovlen = 1;
2088 msgh.msg_control = (caddr_t) buff;
2089 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002090
ajs5c333492005-02-23 15:43:01 +00002091 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2092 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002093 {
ajs5c333492005-02-23 15:43:01 +00002094 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2095 return NULL;
2096 }
paul69310a62005-05-11 18:09:59 +00002097 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002098 {
2099 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2100 "(ip header size is %u)",
2101 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002102 return NULL;
2103 }
paul18b12c32004-10-05 14:38:29 +00002104
ajs5c333492005-02-23 15:43:01 +00002105 /* Note that there should not be alignment problems with this assignment
2106 because this is at the beginning of the stream data buffer. */
2107 iph = (struct ip *) STREAM_DATA(ibuf);
2108 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002109
ajs5c333492005-02-23 15:43:01 +00002110 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002111
paul239aecc2003-12-08 10:34:54 +00002112#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002113 /*
2114 * Kernel network code touches incoming IP header parameters,
2115 * before protocol specific processing.
2116 *
2117 * 1) Convert byteorder to host representation.
2118 * --> ip_len, ip_id, ip_off
2119 *
2120 * 2) Adjust ip_len to strip IP header size!
2121 * --> If user process receives entire IP packet via RAW
2122 * socket, it must consider adding IP header size to
2123 * the "ip_len" field of "ip" structure.
2124 *
2125 * For more details, see <netinet/ip_input.c>.
2126 */
ajs5c333492005-02-23 15:43:01 +00002127 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002128#endif
2129
paul863082d2004-08-19 04:43:43 +00002130 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002131
2132 *ifp = if_lookup_by_index (ifindex);
2133
2134 if (ret != ip_len)
2135 {
ajs5c333492005-02-23 15:43:01 +00002136 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2137 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002138 return NULL;
2139 }
2140
2141 return ibuf;
2142}
2143
paul4dadc292005-05-06 21:37:42 +00002144static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002145ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002146 struct ip *iph, struct ospf_header *ospfh)
2147{
2148 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002149 struct ospf_vl_data *vl_data;
2150 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002151 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002152
2153 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2154 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002155 return NULL;
paul718e3742002-12-13 20:15:29 +00002156
pauld3f0d622004-05-05 15:27:15 +00002157 /* look for local OSPF interface matching the destination
2158 * to determine Area ID. We presume therefore the destination address
2159 * is unique, or at least (for "unnumbered" links), not used in other
2160 * areas
2161 */
2162 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2163 iph->ip_dst)) == NULL)
2164 return NULL;
paul718e3742002-12-13 20:15:29 +00002165
paul1eb8ef22005-04-07 07:30:20 +00002166 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002167 {
paul020709f2003-04-04 02:44:16 +00002168 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002169 if (!vl_area)
2170 continue;
2171
2172 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2173 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2174 {
2175 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002176 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002177 IF_NAME (vl_data->vl_oi));
2178 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2179 {
2180 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002181 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002182 return NULL;
2183 }
2184
2185 return vl_data->vl_oi;
2186 }
2187 }
2188
2189 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002190 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002191
pauld3f0d622004-05-05 15:27:15 +00002192 return NULL;
paul718e3742002-12-13 20:15:29 +00002193}
2194
paul4dadc292005-05-06 21:37:42 +00002195static inline int
paul718e3742002-12-13 20:15:29 +00002196ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2197{
2198 /* Check match the Area ID of the receiving interface. */
2199 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2200 return 1;
2201
2202 return 0;
2203}
2204
2205/* Unbound socket will accept any Raw IP packets if proto is matched.
2206 To prevent it, compare src IP address and i/f address with masking
2207 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002208static int
paul718e3742002-12-13 20:15:29 +00002209ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2210{
2211 struct in_addr mask, me, him;
2212
2213 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2214 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2215 return 1;
2216
2217 masklen2ip (oi->address->prefixlen, &mask);
2218
2219 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2220 him.s_addr = ip_src.s_addr & mask.s_addr;
2221
2222 if (IPV4_ADDR_SAME (&me, &him))
2223 return 1;
2224
2225 return 0;
2226}
2227
paul4dadc292005-05-06 21:37:42 +00002228static int
paul718e3742002-12-13 20:15:29 +00002229ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2230 struct ospf_header *ospfh)
2231{
2232 int ret = 0;
2233 struct crypt_key *ck;
2234
2235 switch (ntohs (ospfh->auth_type))
2236 {
2237 case OSPF_AUTH_NULL:
2238 ret = 1;
2239 break;
2240 case OSPF_AUTH_SIMPLE:
2241 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2242 ret = 1;
2243 else
2244 ret = 0;
2245 break;
2246 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002247 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002248 {
2249 ret = 0;
2250 break;
2251 }
2252
2253 /* This is very basic, the digest processing is elsewhere */
2254 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2255 ospfh->u.crypt.key_id == ck->key_id &&
2256 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2257 ret = 1;
2258 else
2259 ret = 0;
2260 break;
2261 default:
2262 ret = 0;
2263 break;
2264 }
2265
2266 return ret;
2267}
2268
paul4dadc292005-05-06 21:37:42 +00002269static int
paul718e3742002-12-13 20:15:29 +00002270ospf_check_sum (struct ospf_header *ospfh)
2271{
2272 u_int32_t ret;
2273 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002274
2275 /* clear auth_data for checksum. */
2276 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2277
2278 /* keep checksum and clear. */
2279 sum = ospfh->checksum;
2280 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2281
2282 /* calculate checksum. */
2283 ret = in_cksum (ospfh, ntohs (ospfh->length));
2284
2285 if (ret != sum)
2286 {
2287 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2288 ret, sum);
2289 return 0;
2290 }
2291
2292 return 1;
2293}
2294
2295/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002296static int
paul718e3742002-12-13 20:15:29 +00002297ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2298 struct ip *iph, struct ospf_header *ospfh)
2299{
2300 /* check version. */
2301 if (ospfh->version != OSPF_VERSION)
2302 {
2303 zlog_warn ("interface %s: ospf_read version number mismatch.",
2304 IF_NAME (oi));
2305 return -1;
2306 }
2307
2308 /* Check Area ID. */
2309 if (!ospf_check_area_id (oi, ospfh))
2310 {
2311 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2312 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2313 return -1;
2314 }
2315
2316 /* Check network mask, Silently discarded. */
2317 if (! ospf_check_network_mask (oi, iph->ip_src))
2318 {
2319 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2320 IF_NAME (oi), inet_ntoa (iph->ip_src));
2321 return -1;
2322 }
2323
2324 /* Check authentication. */
2325 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2326 {
paulc6371712006-01-17 17:49:53 +00002327 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2328 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002329 return -1;
2330 }
2331
2332 if (! ospf_check_auth (oi, ibuf, ospfh))
2333 {
2334 zlog_warn ("interface %s: ospf_read authentication failed.",
2335 IF_NAME (oi));
2336 return -1;
2337 }
2338
2339 /* if check sum is invalid, packet is discarded. */
2340 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2341 {
2342 if (! ospf_check_sum (ospfh))
2343 {
2344 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2345 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2346 return -1;
2347 }
2348 }
2349 else
2350 {
2351 if (ospfh->checksum != 0)
2352 return -1;
2353 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2354 {
2355 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2356 IF_NAME (oi));
2357 return -1;
2358 }
2359 }
2360
2361 return 0;
2362}
2363
2364/* Starting point of packet process function. */
2365int
2366ospf_read (struct thread *thread)
2367{
2368 int ret;
2369 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002370 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002371 struct ospf_interface *oi;
2372 struct ip *iph;
2373 struct ospf_header *ospfh;
2374 u_int16_t length;
2375 struct interface *ifp;
2376
2377 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002378 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002379
2380 /* prepare for next packet. */
2381 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002382
2383 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002384 stream_reset(ospf->ibuf);
2385 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002386 return -1;
2387
ajs5c333492005-02-23 15:43:01 +00002388 /* Note that there should not be alignment problems with this assignment
2389 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002390 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002391 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002392
paulac191232004-10-22 12:05:17 +00002393 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002394 /* Handle cases where the platform does not support retrieving the ifindex,
2395 and also platforms (such as Solaris 8) that claim to support ifindex
2396 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002397 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002398
pauld3f0d622004-05-05 15:27:15 +00002399 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002400 return 0;
paul718e3742002-12-13 20:15:29 +00002401
2402 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002403 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002404 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002405
paul718e3742002-12-13 20:15:29 +00002406 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002407 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002408 {
pauld3241812003-09-29 12:42:39 +00002409 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2410 {
ajs2a42e282004-12-08 18:43:03 +00002411 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002412 inet_ntoa (iph->ip_src));
2413 }
paul718e3742002-12-13 20:15:29 +00002414 return 0;
2415 }
2416
2417 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002418 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002419
2420 /* Get ospf packet header. */
2421 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2422
2423 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002424 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002425
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002426 /* If incoming interface is passive one, ignore it. */
2427 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2428 {
2429 char buf[3][INET_ADDRSTRLEN];
2430
2431 if (IS_DEBUG_OSPF_EVENT)
2432 zlog_debug ("ignoring packet from router %s sent to %s, "
2433 "received on a passive interface, %s",
2434 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2435 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2436 inet_ntop(AF_INET, &oi->address->u.prefix4,
2437 buf[2], sizeof(buf[2])));
2438
2439 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2440 {
2441 /* Try to fix multicast membership.
2442 * Some OS:es may have problems in this area,
2443 * make sure it is removed.
2444 */
2445 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2446 ospf_if_set_multicast(oi);
2447 }
2448 return 0;
2449 }
2450
2451
pauld3f0d622004-05-05 15:27:15 +00002452 /* if no local ospf_interface,
2453 * or header area is backbone but ospf_interface is not
2454 * check for VLINK interface
2455 */
2456 if ( (oi == NULL) ||
2457 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2458 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2459 )
2460 {
2461 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2462 {
Paul Jakma88871b12006-06-15 11:41:19 +00002463 if (IS_DEBUG_OSPF_EVENT)
2464 zlog_debug ("Packet from [%s] received on link %s"
2465 " but no ospf_interface",
2466 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002467 return 0;
2468 }
2469 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002470
pauld3f0d622004-05-05 15:27:15 +00002471 /* else it must be a local ospf interface, check it was received on
2472 * correct link
2473 */
2474 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002475 {
Paul Jakma11637432009-08-11 12:25:42 +01002476 if (IS_DEBUG_OSPF_EVENT)
2477 zlog_warn ("Packet from [%s] received on wrong link %s",
2478 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002479 return 0;
2480 }
ajs847947f2005-02-02 18:38:48 +00002481 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002482 {
ajsba6454e2005-02-08 15:37:30 +00002483 char buf[2][INET_ADDRSTRLEN];
2484 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002485 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002486 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2487 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2488 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002489 /* Fix multicast memberships? */
2490 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002491 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002492 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002493 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002494 if (oi->multicast_memberships)
2495 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002496 return 0;
2497 }
paul718e3742002-12-13 20:15:29 +00002498
2499 /*
2500 * If the received packet is destined for AllDRouters, the packet
2501 * should be accepted only if the received ospf interface state is
2502 * either DR or Backup -- endo.
2503 */
2504 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2505 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2506 {
ajsba6454e2005-02-08 15:37:30 +00002507 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002508 inet_ntoa (iph->ip_src), IF_NAME (oi),
2509 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002510 /* Try to fix multicast membership. */
2511 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2512 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002513 return 0;
2514 }
2515
2516 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002517 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2518 {
paul718e3742002-12-13 20:15:29 +00002519 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002520 {
ajs2a42e282004-12-08 18:43:03 +00002521 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002522 ospf_packet_dump (ibuf);
2523 }
paul718e3742002-12-13 20:15:29 +00002524
ajs2a42e282004-12-08 18:43:03 +00002525 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002526 ospf_packet_type_str[ospfh->type],
2527 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002528 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2529 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002530
2531 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002532 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002533 }
paul718e3742002-12-13 20:15:29 +00002534
2535 /* Some header verification. */
2536 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2537 if (ret < 0)
2538 {
pauld3241812003-09-29 12:42:39 +00002539 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2540 {
ajs2a42e282004-12-08 18:43:03 +00002541 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002542 "dropping.",
2543 ospf_packet_type_str[ospfh->type],
2544 inet_ntoa (iph->ip_src));
2545 }
paul718e3742002-12-13 20:15:29 +00002546 return ret;
2547 }
2548
paul9985f832005-02-09 15:51:56 +00002549 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002550
2551 /* Adjust size to message length. */
2552 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2553
2554 /* Read rest of the packet and call each sort of packet routine. */
2555 switch (ospfh->type)
2556 {
2557 case OSPF_MSG_HELLO:
2558 ospf_hello (iph, ospfh, ibuf, oi, length);
2559 break;
2560 case OSPF_MSG_DB_DESC:
2561 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2562 break;
2563 case OSPF_MSG_LS_REQ:
2564 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2565 break;
2566 case OSPF_MSG_LS_UPD:
2567 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2568 break;
2569 case OSPF_MSG_LS_ACK:
2570 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2571 break;
2572 default:
2573 zlog (NULL, LOG_WARNING,
2574 "interface %s: OSPF packet header type %d is illegal",
2575 IF_NAME (oi), ospfh->type);
2576 break;
2577 }
2578
paul718e3742002-12-13 20:15:29 +00002579 return 0;
2580}
2581
2582/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002583static void
paul718e3742002-12-13 20:15:29 +00002584ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2585{
2586 struct ospf_header *ospfh;
2587
2588 ospfh = (struct ospf_header *) STREAM_DATA (s);
2589
2590 ospfh->version = (u_char) OSPF_VERSION;
2591 ospfh->type = (u_char) type;
2592
paul68980082003-03-25 05:07:42 +00002593 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002594
2595 ospfh->checksum = 0;
2596 ospfh->area_id = oi->area->area_id;
2597 ospfh->auth_type = htons (ospf_auth_type (oi));
2598
2599 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2600
paul9985f832005-02-09 15:51:56 +00002601 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002602}
2603
2604/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002605static int
paul718e3742002-12-13 20:15:29 +00002606ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2607{
2608 struct crypt_key *ck;
2609
2610 switch (ospf_auth_type (oi))
2611 {
2612 case OSPF_AUTH_NULL:
2613 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2614 break;
2615 case OSPF_AUTH_SIMPLE:
2616 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2617 OSPF_AUTH_SIMPLE_SIZE);
2618 break;
2619 case OSPF_AUTH_CRYPTOGRAPHIC:
2620 /* If key is not set, then set 0. */
2621 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2622 {
2623 ospfh->u.crypt.zero = 0;
2624 ospfh->u.crypt.key_id = 0;
2625 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2626 }
2627 else
2628 {
paul1eb8ef22005-04-07 07:30:20 +00002629 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002630 ospfh->u.crypt.zero = 0;
2631 ospfh->u.crypt.key_id = ck->key_id;
2632 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2633 }
2634 /* note: the seq is done in ospf_make_md5_digest() */
2635 break;
2636 default:
2637 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2638 break;
2639 }
2640
2641 return 0;
2642}
2643
2644/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002645static void
paul718e3742002-12-13 20:15:29 +00002646ospf_fill_header (struct ospf_interface *oi,
2647 struct stream *s, u_int16_t length)
2648{
2649 struct ospf_header *ospfh;
2650
2651 ospfh = (struct ospf_header *) STREAM_DATA (s);
2652
2653 /* Fill length. */
2654 ospfh->length = htons (length);
2655
2656 /* Calculate checksum. */
2657 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2658 ospfh->checksum = in_cksum (ospfh, length);
2659 else
2660 ospfh->checksum = 0;
2661
2662 /* Add Authentication Data. */
2663 ospf_make_auth (oi, ospfh);
2664}
2665
paul4dadc292005-05-06 21:37:42 +00002666static int
paul718e3742002-12-13 20:15:29 +00002667ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2668{
2669 struct ospf_neighbor *nbr;
2670 struct route_node *rn;
2671 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2672 struct in_addr mask;
2673 unsigned long p;
2674 int flag = 0;
2675
2676 /* Set netmask of interface. */
2677 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2678 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2679 masklen2ip (oi->address->prefixlen, &mask);
2680 else
2681 memset ((char *) &mask, 0, sizeof (struct in_addr));
2682 stream_put_ipv4 (s, mask.s_addr);
2683
2684 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002685 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2686 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2687 else
2688 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002689
2690 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002691 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002692 OPTIONS(oi), IF_NAME (oi));
2693
2694 /* Set Options. */
2695 stream_putc (s, OPTIONS (oi));
2696
2697 /* Set Router Priority. */
2698 stream_putc (s, PRIORITY (oi));
2699
2700 /* Set Router Dead Interval. */
2701 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2702
2703 /* Set Designated Router. */
2704 stream_put_ipv4 (s, DR (oi).s_addr);
2705
paul9985f832005-02-09 15:51:56 +00002706 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002707
2708 /* Set Backup Designated Router. */
2709 stream_put_ipv4 (s, BDR (oi).s_addr);
2710
2711 /* Add neighbor seen. */
2712 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002713 if ((nbr = rn->info))
2714 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2715 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2716 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2717 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002718 {
2719 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002720 if (nbr->d_router.s_addr != 0
2721 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2722 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2723 flag = 1;
paul718e3742002-12-13 20:15:29 +00002724
2725 stream_put_ipv4 (s, nbr->router_id.s_addr);
2726 length += 4;
2727 }
2728
2729 /* Let neighbor generate BackupSeen. */
2730 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002731 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002732
2733 return length;
2734}
2735
paul4dadc292005-05-06 21:37:42 +00002736static int
paul718e3742002-12-13 20:15:29 +00002737ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2738 struct stream *s)
2739{
2740 struct ospf_lsa *lsa;
2741 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2742 u_char options;
2743 unsigned long pp;
2744 int i;
2745 struct ospf_lsdb *lsdb;
2746
2747 /* Set Interface MTU. */
2748 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2749 stream_putw (s, 0);
2750 else
2751 stream_putw (s, oi->ifp->mtu);
2752
2753 /* Set Options. */
2754 options = OPTIONS (oi);
2755#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002756 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002757 {
2758 if (IS_SET_DD_I (nbr->dd_flags)
2759 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2760 /*
2761 * Set O-bit in the outgoing DD packet for capablity negotiation,
2762 * if one of following case is applicable.
2763 *
2764 * 1) WaitTimer expiration event triggered the neighbor state to
2765 * change to Exstart, but no (valid) DD packet has received
2766 * from the neighbor yet.
2767 *
2768 * 2) At least one DD packet with O-bit on has received from the
2769 * neighbor.
2770 */
2771 SET_FLAG (options, OSPF_OPTION_O);
2772 }
2773#endif /* HAVE_OPAQUE_LSA */
2774 stream_putc (s, options);
2775
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002776 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002777 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002778 stream_putc (s, nbr->dd_flags);
2779
2780 /* Set DD Sequence Number. */
2781 stream_putl (s, nbr->dd_seqnum);
2782
Paul Jakmab5aeb442006-08-30 18:47:37 +00002783 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002784 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002785 goto empty;
paul718e3742002-12-13 20:15:29 +00002786
2787 /* Describe LSA Header from Database Summary List. */
2788 lsdb = &nbr->db_sum;
2789
2790 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2791 {
2792 struct route_table *table = lsdb->type[i].db;
2793 struct route_node *rn;
2794
2795 for (rn = route_top (table); rn; rn = route_next (rn))
2796 if ((lsa = rn->info) != NULL)
2797 {
2798#ifdef HAVE_OPAQUE_LSA
2799 if (IS_OPAQUE_LSA (lsa->data->type)
2800 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2801 {
2802 /* Suppress advertising opaque-informations. */
2803 /* Remove LSA from DB summary list. */
2804 ospf_lsdb_delete (lsdb, lsa);
2805 continue;
2806 }
2807#endif /* HAVE_OPAQUE_LSA */
2808
2809 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2810 {
2811 struct lsa_header *lsah;
2812 u_int16_t ls_age;
2813
2814 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002815 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002816 break;
2817
2818 /* Keep pointer to LS age. */
2819 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002820 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002821
2822 /* Proceed stream pointer. */
2823 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2824 length += OSPF_LSA_HEADER_SIZE;
2825
2826 /* Set LS age. */
2827 ls_age = LS_AGE (lsa);
2828 lsah->ls_age = htons (ls_age);
2829
2830 }
2831
2832 /* Remove LSA from DB summary list. */
2833 ospf_lsdb_delete (lsdb, lsa);
2834 }
2835 }
2836
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002837 /* Update 'More' bit */
2838 if (ospf_db_summary_isempty (nbr))
2839 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002840empty:
2841 if (nbr->state >= NSM_Exchange)
2842 {
2843 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2844 /* Rewrite DD flags */
2845 stream_putc_at (s, pp, nbr->dd_flags);
2846 }
2847 else
2848 {
2849 assert (IS_SET_DD_M(nbr->dd_flags));
2850 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002851 }
paul718e3742002-12-13 20:15:29 +00002852 return length;
2853}
2854
paul4dadc292005-05-06 21:37:42 +00002855static int
paul718e3742002-12-13 20:15:29 +00002856ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2857 unsigned long delta, struct ospf_neighbor *nbr,
2858 struct ospf_lsa *lsa)
2859{
2860 struct ospf_interface *oi;
2861
2862 oi = nbr->oi;
2863
2864 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002865 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002866 return 0;
2867
2868 stream_putl (s, lsa->data->type);
2869 stream_put_ipv4 (s, lsa->data->id.s_addr);
2870 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2871
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002872 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002873 nbr->ls_req_last = ospf_lsa_lock (lsa);
2874
2875 *length += 12;
2876 return 1;
2877}
2878
paul4dadc292005-05-06 21:37:42 +00002879static int
paul718e3742002-12-13 20:15:29 +00002880ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2881{
2882 struct ospf_lsa *lsa;
2883 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002884 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002885 struct route_table *table;
2886 struct route_node *rn;
2887 int i;
2888 struct ospf_lsdb *lsdb;
2889
2890 lsdb = &nbr->ls_req;
2891
2892 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2893 {
2894 table = lsdb->type[i].db;
2895 for (rn = route_top (table); rn; rn = route_next (rn))
2896 if ((lsa = (rn->info)) != NULL)
2897 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2898 {
2899 route_unlock_node (rn);
2900 break;
2901 }
2902 }
2903 return length;
2904}
2905
paul4dadc292005-05-06 21:37:42 +00002906static int
paul718e3742002-12-13 20:15:29 +00002907ls_age_increment (struct ospf_lsa *lsa, int delay)
2908{
2909 int age;
2910
2911 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2912
2913 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2914}
2915
paul4dadc292005-05-06 21:37:42 +00002916static int
hasso52dc7ee2004-09-23 19:18:23 +00002917ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002918{
2919 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002920 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002921 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00002922 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002923 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002924 unsigned long pp;
2925 int count = 0;
2926
2927 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002928 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002929
paul9985f832005-02-09 15:51:56 +00002930 pp = stream_get_endp (s);
2931 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002932 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00002933
gdt86f1fd92005-01-10 14:20:43 +00002934 /* Calculate amount of packet usable for data. */
2935 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2936
paul718e3742002-12-13 20:15:29 +00002937 while ((node = listhead (update)) != NULL)
2938 {
2939 struct lsa_header *lsah;
2940 u_int16_t ls_age;
2941
2942 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002943 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002944
paul1eb8ef22005-04-07 07:30:20 +00002945 lsa = listgetdata (node);
2946
paul718e3742002-12-13 20:15:29 +00002947 assert (lsa->data);
2948
paul68b73392004-09-12 14:21:37 +00002949 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002950 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002951 break;
2952
paul718e3742002-12-13 20:15:29 +00002953 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002954 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002955
2956 /* Put LSA to Link State Request. */
2957 stream_put (s, lsa->data, ntohs (lsa->data->length));
2958
2959 /* Set LS age. */
2960 /* each hop must increment an lsa_age by transmit_delay
2961 of OSPF interface */
2962 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2963 lsah->ls_age = htons (ls_age);
2964
2965 length += ntohs (lsa->data->length);
2966 count++;
2967
2968 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002969 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00002970 }
2971
2972 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002973 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002974
2975 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002976 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002977 return length;
2978}
2979
paul4dadc292005-05-06 21:37:42 +00002980static int
hasso52dc7ee2004-09-23 19:18:23 +00002981ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002982{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002983 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002984 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002985 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002986 struct ospf_lsa *lsa;
2987
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002988 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002989 {
paul718e3742002-12-13 20:15:29 +00002990 assert (lsa);
2991
gdt86f1fd92005-01-10 14:20:43 +00002992 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002993 break;
2994
2995 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2996 length += OSPF_LSA_HEADER_SIZE;
2997
paul718e3742002-12-13 20:15:29 +00002998 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002999 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003000 }
3001
paul718e3742002-12-13 20:15:29 +00003002 return length;
3003}
3004
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003005static void
3006ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003007{
3008 struct ospf_packet *op;
3009 u_int16_t length = OSPF_HEADER_SIZE;
3010
3011 op = ospf_packet_new (oi->ifp->mtu);
3012
3013 /* Prepare OSPF common header. */
3014 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3015
3016 /* Prepare OSPF Hello body. */
3017 length += ospf_make_hello (oi, op->s);
3018
3019 /* Fill OSPF header. */
3020 ospf_fill_header (oi, op->s, length);
3021
3022 /* Set packet length. */
3023 op->length = length;
3024
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003025 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003026
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003027 /* Add packet to the top of the interface output queue, so that they
3028 * can't get delayed by things like long queues of LS Update packets
3029 */
3030 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003031
3032 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003033 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003034}
3035
paul4dadc292005-05-06 21:37:42 +00003036static void
paul718e3742002-12-13 20:15:29 +00003037ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3038{
3039 struct ospf_interface *oi;
3040
3041 oi = nbr_nbma->oi;
3042 assert(oi);
3043
3044 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003045 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003046 return;
3047
3048 if (oi->type != OSPF_IFTYPE_NBMA)
3049 return;
3050
3051 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3052 return;
3053
3054 if (PRIORITY(oi) == 0)
3055 return;
3056
3057 if (nbr_nbma->priority == 0
3058 && oi->state != ISM_DR && oi->state != ISM_Backup)
3059 return;
3060
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003061 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003062}
3063
3064int
3065ospf_poll_timer (struct thread *thread)
3066{
3067 struct ospf_nbr_nbma *nbr_nbma;
3068
3069 nbr_nbma = THREAD_ARG (thread);
3070 nbr_nbma->t_poll = NULL;
3071
3072 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003073 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003074 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3075
3076 ospf_poll_send (nbr_nbma);
3077
3078 if (nbr_nbma->v_poll > 0)
3079 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3080 nbr_nbma->v_poll);
3081
3082 return 0;
3083}
3084
3085
3086int
3087ospf_hello_reply_timer (struct thread *thread)
3088{
3089 struct ospf_neighbor *nbr;
3090
3091 nbr = THREAD_ARG (thread);
3092 nbr->t_hello_reply = NULL;
3093
3094 assert (nbr->oi);
3095
3096 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003097 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003098 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3099
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003100 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003101
3102 return 0;
3103}
3104
3105/* Send OSPF Hello. */
3106void
3107ospf_hello_send (struct ospf_interface *oi)
3108{
paul718e3742002-12-13 20:15:29 +00003109 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003110 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003111 return;
3112
paul718e3742002-12-13 20:15:29 +00003113 if (oi->type == OSPF_IFTYPE_NBMA)
3114 {
3115 struct ospf_neighbor *nbr;
3116 struct route_node *rn;
3117
3118 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3119 if ((nbr = rn->info))
3120 if (nbr != oi->nbr_self)
3121 if (nbr->state != NSM_Down)
3122 {
3123 /* RFC 2328 Section 9.5.1
3124 If the router is not eligible to become Designated Router,
3125 it must periodically send Hello Packets to both the
3126 Designated Router and the Backup Designated Router (if they
3127 exist). */
3128 if (PRIORITY(oi) == 0 &&
3129 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3130 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3131 continue;
3132
3133 /* If the router is eligible to become Designated Router, it
3134 must periodically send Hello Packets to all neighbors that
3135 are also eligible. In addition, if the router is itself the
3136 Designated Router or Backup Designated Router, it must also
3137 send periodic Hello Packets to all other neighbors. */
3138
3139 if (nbr->priority == 0 && oi->state == ISM_DROther)
3140 continue;
3141 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003142 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003143 }
paul718e3742002-12-13 20:15:29 +00003144 }
3145 else
3146 {
3147 /* Decide destination address. */
3148 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003149 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3150 else
3151 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003152 }
3153}
3154
3155/* Send OSPF Database Description. */
3156void
3157ospf_db_desc_send (struct ospf_neighbor *nbr)
3158{
3159 struct ospf_interface *oi;
3160 struct ospf_packet *op;
3161 u_int16_t length = OSPF_HEADER_SIZE;
3162
3163 oi = nbr->oi;
3164 op = ospf_packet_new (oi->ifp->mtu);
3165
3166 /* Prepare OSPF common header. */
3167 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3168
3169 /* Prepare OSPF Database Description body. */
3170 length += ospf_make_db_desc (oi, nbr, op->s);
3171
3172 /* Fill OSPF header. */
3173 ospf_fill_header (oi, op->s, length);
3174
3175 /* Set packet length. */
3176 op->length = length;
3177
3178 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003179 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3180 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3181 else
3182 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003183
3184 /* Add packet to the interface output queue. */
3185 ospf_packet_add (oi, op);
3186
3187 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003188 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003189
3190 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3191 if (nbr->last_send)
3192 ospf_packet_free (nbr->last_send);
3193 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003194 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003195}
3196
3197/* Re-send Database Description. */
3198void
3199ospf_db_desc_resend (struct ospf_neighbor *nbr)
3200{
3201 struct ospf_interface *oi;
3202
3203 oi = nbr->oi;
3204
3205 /* Add packet to the interface output queue. */
3206 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3207
3208 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003209 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003210}
3211
3212/* Send Link State Request. */
3213void
3214ospf_ls_req_send (struct ospf_neighbor *nbr)
3215{
3216 struct ospf_interface *oi;
3217 struct ospf_packet *op;
3218 u_int16_t length = OSPF_HEADER_SIZE;
3219
3220 oi = nbr->oi;
3221 op = ospf_packet_new (oi->ifp->mtu);
3222
3223 /* Prepare OSPF common header. */
3224 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3225
3226 /* Prepare OSPF Link State Request body. */
3227 length += ospf_make_ls_req (nbr, op->s);
3228 if (length == OSPF_HEADER_SIZE)
3229 {
3230 ospf_packet_free (op);
3231 return;
3232 }
3233
3234 /* Fill OSPF header. */
3235 ospf_fill_header (oi, op->s, length);
3236
3237 /* Set packet length. */
3238 op->length = length;
3239
3240 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003241 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3242 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3243 else
3244 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003245
3246 /* Add packet to the interface output queue. */
3247 ospf_packet_add (oi, op);
3248
3249 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003250 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003251
3252 /* Add Link State Request Retransmission Timer. */
3253 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3254}
3255
3256/* Send Link State Update with an LSA. */
3257void
3258ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3259 int flag)
3260{
hasso52dc7ee2004-09-23 19:18:23 +00003261 struct list *update;
paul718e3742002-12-13 20:15:29 +00003262
3263 update = list_new ();
3264
3265 listnode_add (update, lsa);
3266 ospf_ls_upd_send (nbr, update, flag);
3267
3268 list_delete (update);
3269}
3270
paul68b73392004-09-12 14:21:37 +00003271/* Determine size for packet. Must be at least big enough to accomodate next
3272 * LSA on list, which may be bigger than MTU size.
3273 *
3274 * Return pointer to new ospf_packet
3275 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3276 * on packet sizes (in which case offending LSA is deleted from update list)
3277 */
3278static struct ospf_packet *
3279ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3280{
3281 struct ospf_lsa *lsa;
3282 struct listnode *ln;
3283 size_t size;
3284 static char warned = 0;
3285
paul1eb8ef22005-04-07 07:30:20 +00003286 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003287 assert (lsa->data);
3288
3289 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3290 > ospf_packet_max (oi))
3291 {
3292 if (!warned)
3293 {
3294 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3295 "will need to fragment. Not optimal. Try divide up"
3296 " your network with areas. Use 'debug ospf packet send'"
3297 " to see details, or look at 'show ip ospf database ..'");
3298 warned = 1;
3299 }
3300
3301 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003302 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003303 " %d bytes originated by %s, will be fragmented!",
3304 inet_ntoa (lsa->data->id),
3305 ntohs (lsa->data->length),
3306 inet_ntoa (lsa->data->adv_router));
3307
3308 /*
3309 * Allocate just enough to fit this LSA only, to avoid including other
3310 * LSAs in fragmented LSA Updates.
3311 */
3312 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3313 + OSPF_LS_UPD_MIN_SIZE;
3314 }
3315 else
3316 size = oi->ifp->mtu;
3317
3318 if (size > OSPF_MAX_PACKET_SIZE)
3319 {
3320 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003321 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003322 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003323 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003324 (long int) size);
paul68b73392004-09-12 14:21:37 +00003325 list_delete_node (update, ln);
3326 return NULL;
3327 }
3328
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003329 /* IP header is built up separately by ospf_write(). This means, that we must
3330 * reduce the "affordable" size just calculated by length of an IP header.
3331 * This makes sure, that even if we manage to fill the payload with LSA data
3332 * completely, the final packet (our data plus IP header) still fits into
3333 * outgoing interface MTU. This correction isn't really meaningful for an
3334 * oversized LSA, but for consistency the correction is done for both cases.
3335 *
3336 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3337 */
3338 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003339}
3340
paul718e3742002-12-13 20:15:29 +00003341static void
hasso52dc7ee2004-09-23 19:18:23 +00003342ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003343 struct in_addr addr)
3344{
3345 struct ospf_packet *op;
3346 u_int16_t length = OSPF_HEADER_SIZE;
3347
3348 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003349 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003350
3351 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003352
3353 /* Prepare OSPF common header. */
3354 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3355
paul59ea14c2004-07-14 20:50:36 +00003356 /* Prepare OSPF Link State Update body.
3357 * Includes Type-7 translation.
3358 */
paul718e3742002-12-13 20:15:29 +00003359 length += ospf_make_ls_upd (oi, update, op->s);
3360
3361 /* Fill OSPF header. */
3362 ospf_fill_header (oi, op->s, length);
3363
3364 /* Set packet length. */
3365 op->length = length;
3366
3367 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003368 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3369 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3370 else
3371 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003372
3373 /* Add packet to the interface output queue. */
3374 ospf_packet_add (oi, op);
3375
3376 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003377 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003378}
3379
3380static int
3381ospf_ls_upd_send_queue_event (struct thread *thread)
3382{
3383 struct ospf_interface *oi = THREAD_ARG(thread);
3384 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003385 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003386 struct list *update;
paul68b73392004-09-12 14:21:37 +00003387 char again = 0;
paul718e3742002-12-13 20:15:29 +00003388
3389 oi->t_ls_upd_event = NULL;
3390
3391 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003392 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003393
paul736d3442003-07-24 23:22:57 +00003394 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003395 {
paul736d3442003-07-24 23:22:57 +00003396 rnext = route_next (rn);
3397
paul718e3742002-12-13 20:15:29 +00003398 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003399 continue;
paul68b73392004-09-12 14:21:37 +00003400
3401 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003402
paul48fe13b2004-07-27 17:40:44 +00003403 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003404
paul68b73392004-09-12 14:21:37 +00003405 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003406 if (listcount(update) == 0)
3407 {
3408 list_delete (rn->info);
3409 rn->info = NULL;
3410 route_unlock_node (rn);
3411 }
3412 else
paul68b73392004-09-12 14:21:37 +00003413 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003414 }
3415
3416 if (again != 0)
3417 {
3418 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003419 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003420 " %d nodes to try again, raising new event", again);
3421 oi->t_ls_upd_event =
3422 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003423 }
3424
3425 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003426 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003427
paul718e3742002-12-13 20:15:29 +00003428 return 0;
3429}
3430
3431void
hasso52dc7ee2004-09-23 19:18:23 +00003432ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003433{
3434 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003435 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003436 struct prefix_ipv4 p;
3437 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003438 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003439
3440 oi = nbr->oi;
3441
3442 p.family = AF_INET;
3443 p.prefixlen = IPV4_MAX_BITLEN;
3444
3445 /* Decide destination address. */
3446 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3447 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003448 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3449 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003450 else if (flag == OSPF_SEND_PACKET_DIRECT)
3451 p.prefix = nbr->address.u.prefix4;
3452 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3453 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003454 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3455 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003456 else
3457 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3458
3459 if (oi->type == OSPF_IFTYPE_NBMA)
3460 {
3461 if (flag == OSPF_SEND_PACKET_INDIRECT)
3462 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3463 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3464 zlog_warn ("* LS-Update is sent to myself.");
3465 }
3466
3467 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3468
3469 if (rn->info == NULL)
3470 rn->info = list_new ();
3471
paul1eb8ef22005-04-07 07:30:20 +00003472 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003473 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003474
3475 if (oi->t_ls_upd_event == NULL)
3476 oi->t_ls_upd_event =
3477 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3478}
3479
3480static void
hasso52dc7ee2004-09-23 19:18:23 +00003481ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3482 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003483{
3484 struct ospf_packet *op;
3485 u_int16_t length = OSPF_HEADER_SIZE;
3486
3487 op = ospf_packet_new (oi->ifp->mtu);
3488
3489 /* Prepare OSPF common header. */
3490 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3491
3492 /* Prepare OSPF Link State Acknowledgment body. */
3493 length += ospf_make_ls_ack (oi, ack, op->s);
3494
3495 /* Fill OSPF header. */
3496 ospf_fill_header (oi, op->s, length);
3497
3498 /* Set packet length. */
3499 op->length = length;
3500
3501 /* Set destination IP address. */
3502 op->dst = dst;
3503
3504 /* Add packet to the interface output queue. */
3505 ospf_packet_add (oi, op);
3506
3507 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003508 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003509}
3510
3511static int
3512ospf_ls_ack_send_event (struct thread *thread)
3513{
3514 struct ospf_interface *oi = THREAD_ARG (thread);
3515
3516 oi->t_ls_ack_direct = NULL;
3517
3518 while (listcount (oi->ls_ack_direct.ls_ack))
3519 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3520 oi->ls_ack_direct.dst);
3521
3522 return 0;
3523}
3524
3525void
3526ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3527{
3528 struct ospf_interface *oi = nbr->oi;
3529
3530 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3531 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3532
3533 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3534
3535 if (oi->t_ls_ack_direct == NULL)
3536 oi->t_ls_ack_direct =
3537 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3538}
3539
3540/* Send Link State Acknowledgment delayed. */
3541void
3542ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3543{
3544 struct in_addr dst;
3545
3546 /* Decide destination address. */
3547 /* RFC2328 Section 13.5 On non-broadcast
3548 networks, delayed Link State Acknowledgment packets must be
3549 unicast separately over each adjacency (i.e., neighbor whose
3550 state is >= Exchange). */
3551 if (oi->type == OSPF_IFTYPE_NBMA)
3552 {
3553 struct ospf_neighbor *nbr;
3554 struct route_node *rn;
3555
3556 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3557 if ((nbr = rn->info) != NULL)
3558 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3559 while (listcount (oi->ls_ack))
3560 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3561 return;
3562 }
3563 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3564 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3565 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3566 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3567 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3568 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003569 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3570 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003571 else
3572 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3573
3574 while (listcount (oi->ls_ack))
3575 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3576}