blob: d2504c78d6e63924e7b3d7882ecfcf5964743ecf [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. */
Denis Ovsienko272ca1e2012-01-15 19:12:19 +040053const struct message ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000054{
Denis Ovsienko272ca1e2012-01-15 19:12:19 +040055 { OSPF_MSG_HELLO, "Hello" },
56 { OSPF_MSG_DB_DESC, "Database Description" },
57 { OSPF_MSG_LS_REQ, "Link State Request" },
58 { OSPF_MSG_LS_UPD, "Link State Update" },
59 { OSPF_MSG_LS_ACK, "Link State Acknowledgment" },
paul718e3742002-12-13 20:15:29 +000060};
Denis Ovsienko272ca1e2012-01-15 19:12:19 +040061const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) /
62 sizeof (ospf_packet_type_str[0]);
paul718e3742002-12-13 20:15:29 +000063
Denis Ovsienko75c8eab2012-01-30 15:41:39 +040064/* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of
65 particular types, offset is the "type" field of a packet. */
66static const u_int16_t ospf_packet_minlen[] =
67{
68 0,
69 OSPF_HELLO_MIN_SIZE,
70 OSPF_DB_DESC_MIN_SIZE,
71 OSPF_LS_REQ_MIN_SIZE,
72 OSPF_LS_UPD_MIN_SIZE,
73 OSPF_LS_ACK_MIN_SIZE,
74};
75
Denis Ovsienko4e31de72012-02-17 16:20:50 +040076/* Minimum (besides OSPF_LSA_HEADER_SIZE) lengths for LSAs of particular
77 types, offset is the "LSA type" field. */
78static const u_int16_t ospf_lsa_minlen[] =
79{
80 0,
81 OSPF_ROUTER_LSA_MIN_SIZE,
82 OSPF_NETWORK_LSA_MIN_SIZE,
83 OSPF_SUMMARY_LSA_MIN_SIZE,
84 OSPF_SUMMARY_LSA_MIN_SIZE,
85 OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
86 0,
87 OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
88 0,
89 0,
90 0,
91 0,
92};
93
Denis Ovsienkobd5651f2012-02-26 17:59:43 +040094/* for ospf_check_auth() */
95static int ospf_check_sum (struct ospf_header *);
96
paul718e3742002-12-13 20:15:29 +000097/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000098static int
paul718e3742002-12-13 20:15:29 +000099ospf_auth_type (struct ospf_interface *oi)
100{
101 int auth_type;
102
103 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
104 auth_type = oi->area->auth_type;
105 else
106 auth_type = OSPF_IF_PARAM (oi, auth_type);
107
108 /* Handle case where MD5 key list is not configured aka Cisco */
109 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
110 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
111 return OSPF_AUTH_NULL;
112
113 return auth_type;
114
115}
116
paul718e3742002-12-13 20:15:29 +0000117struct ospf_packet *
118ospf_packet_new (size_t size)
119{
120 struct ospf_packet *new;
121
122 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
123 new->s = stream_new (size);
124
125 return new;
126}
127
128void
129ospf_packet_free (struct ospf_packet *op)
130{
131 if (op->s)
132 stream_free (op->s);
133
134 XFREE (MTYPE_OSPF_PACKET, op);
135
136 op = NULL;
137}
138
139struct ospf_fifo *
140ospf_fifo_new ()
141{
142 struct ospf_fifo *new;
143
144 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
145 return new;
146}
147
148/* Add new packet to fifo. */
149void
150ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
151{
152 if (fifo->tail)
153 fifo->tail->next = op;
154 else
155 fifo->head = op;
156
157 fifo->tail = op;
158
159 fifo->count++;
160}
161
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000162/* Add new packet to head of fifo. */
163static void
164ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
165{
166 op->next = fifo->head;
167
168 if (fifo->tail == NULL)
169 fifo->tail = op;
170
171 fifo->head = op;
172
173 fifo->count++;
174}
175
paul718e3742002-12-13 20:15:29 +0000176/* Delete first packet from fifo. */
177struct ospf_packet *
178ospf_fifo_pop (struct ospf_fifo *fifo)
179{
180 struct ospf_packet *op;
181
182 op = fifo->head;
183
184 if (op)
185 {
186 fifo->head = op->next;
187
188 if (fifo->head == NULL)
189 fifo->tail = NULL;
190
191 fifo->count--;
192 }
193
194 return op;
195}
196
197/* Return first fifo entry. */
198struct ospf_packet *
199ospf_fifo_head (struct ospf_fifo *fifo)
200{
201 return fifo->head;
202}
203
204/* Flush ospf packet fifo. */
205void
206ospf_fifo_flush (struct ospf_fifo *fifo)
207{
208 struct ospf_packet *op;
209 struct ospf_packet *next;
210
211 for (op = fifo->head; op; op = next)
212 {
213 next = op->next;
214 ospf_packet_free (op);
215 }
216 fifo->head = fifo->tail = NULL;
217 fifo->count = 0;
218}
219
220/* Free ospf packet fifo. */
221void
222ospf_fifo_free (struct ospf_fifo *fifo)
223{
224 ospf_fifo_flush (fifo);
225
226 XFREE (MTYPE_OSPF_FIFO, fifo);
227}
228
229void
230ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
231{
ajsc3eab872005-01-29 15:52:07 +0000232 if (!oi->obuf)
233 {
234 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
235 "destination %s) called with NULL obuf, ignoring "
236 "(please report this bug)!\n",
237 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400238 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
ajsc3eab872005-01-29 15:52:07 +0000239 inet_ntoa (op->dst));
240 return;
241 }
242
paul718e3742002-12-13 20:15:29 +0000243 /* Add packet to end of queue. */
244 ospf_fifo_push (oi->obuf, op);
245
246 /* Debug of packet fifo*/
247 /* ospf_fifo_debug (oi->obuf); */
248}
249
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000250static void
251ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
252{
253 if (!oi->obuf)
254 {
255 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
256 "destination %s) called with NULL obuf, ignoring "
257 "(please report this bug)!\n",
258 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko7e0e2cb2012-01-20 22:32:10 +0400259 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000260 inet_ntoa (op->dst));
261 return;
262 }
263
264 /* Add packet to head of queue. */
265 ospf_fifo_push_head (oi->obuf, op);
266
267 /* Debug of packet fifo*/
268 /* ospf_fifo_debug (oi->obuf); */
269}
270
paul718e3742002-12-13 20:15:29 +0000271void
272ospf_packet_delete (struct ospf_interface *oi)
273{
274 struct ospf_packet *op;
275
276 op = ospf_fifo_pop (oi->obuf);
277
278 if (op)
279 ospf_packet_free (op);
280}
281
paul718e3742002-12-13 20:15:29 +0000282struct ospf_packet *
283ospf_packet_dup (struct ospf_packet *op)
284{
285 struct ospf_packet *new;
286
paul37163d62003-02-03 18:40:56 +0000287 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000288 /* XXX size_t */
289 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
290 (u_long)STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000291
292 /* Reserve space for MD5 authentication that may be added later. */
293 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000294 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000295
296 new->dst = op->dst;
297 new->length = op->length;
298
299 return new;
300}
301
gdt86f1fd92005-01-10 14:20:43 +0000302/* XXX inline */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100303static unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000304ospf_packet_authspace (struct ospf_interface *oi)
305{
306 int auth = 0;
307
308 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
309 auth = OSPF_AUTH_MD5_SIZE;
310
311 return auth;
312}
313
paul4dadc292005-05-06 21:37:42 +0000314static unsigned int
paul718e3742002-12-13 20:15:29 +0000315ospf_packet_max (struct ospf_interface *oi)
316{
317 int max;
318
gdt86f1fd92005-01-10 14:20:43 +0000319 max = oi->ifp->mtu - ospf_packet_authspace(oi);
320
paul68b73392004-09-12 14:21:37 +0000321 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000322
323 return max;
324}
325
David Lamparter6b0655a2014-06-04 06:53:35 +0200326
paul4dadc292005-05-06 21:37:42 +0000327static int
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400328ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +0000329{
vincentc1a03d42005-09-28 15:47:44 +0000330 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000331 unsigned char digest[OSPF_AUTH_MD5_SIZE];
paul718e3742002-12-13 20:15:29 +0000332 struct crypt_key *ck;
paul718e3742002-12-13 20:15:29 +0000333 struct ospf_neighbor *nbr;
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400334 u_int16_t length = ntohs (ospfh->length);
paul718e3742002-12-13 20:15:29 +0000335
paul718e3742002-12-13 20:15:29 +0000336 /* Get secret key. */
337 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
338 ospfh->u.crypt.key_id);
339 if (ck == NULL)
340 {
341 zlog_warn ("interface %s: ospf_check_md5 no key %d",
342 IF_NAME (oi), ospfh->u.crypt.key_id);
343 return 0;
344 }
345
346 /* check crypto seqnum. */
347 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
348
349 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
350 {
351 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
352 IF_NAME (oi),
353 ntohl(ospfh->u.crypt.crypt_seqnum),
354 ntohl(nbr->crypt_seqnum));
355 return 0;
356 }
357
358 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000359 memset(&ctx, 0, sizeof(ctx));
360 MD5Init(&ctx);
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400361 MD5Update(&ctx, ospfh, length);
vincentc1a03d42005-09-28 15:47:44 +0000362 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
363 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000364
365 /* compare the two */
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400366 if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE))
paul718e3742002-12-13 20:15:29 +0000367 {
368 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
369 IF_NAME (oi));
370 return 0;
371 }
372
373 /* save neighbor's crypt_seqnum */
374 if (nbr)
375 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
376 return 1;
377}
378
379/* This function is called from ospf_write(), it will detect the
380 authentication scheme and if it is MD5, it will change the sequence
381 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000382static int
paul718e3742002-12-13 20:15:29 +0000383ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
384{
385 struct ospf_header *ospfh;
Joakim Tjernlundea2a5982009-11-26 12:23:07 +0000386 unsigned char digest[OSPF_AUTH_MD5_SIZE] = {0};
vincentc1a03d42005-09-28 15:47:44 +0000387 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000388 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000389 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000390 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000391 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000392
393 ibuf = STREAM_DATA (op->s);
394 ospfh = (struct ospf_header *) ibuf;
395
396 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
397 return 0;
398
399 /* We do this here so when we dup a packet, we don't have to
Paul Jakma2518efd2006-08-27 06:49:29 +0000400 waste CPU rewriting other headers.
401
402 Note that quagga_time /deliberately/ is not used here */
paul9483e152002-12-13 20:55:25 +0000403 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000404 if (t > oi->crypt_seqnum)
405 oi->crypt_seqnum = t;
406 else
407 oi->crypt_seqnum++;
408
paul9483e152002-12-13 20:55:25 +0000409 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000410
411 /* Get MD5 Authentication key from auth_key list. */
412 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
Joakim Tjernlundea2a5982009-11-26 12:23:07 +0000413 auth_key = (const u_int8_t *) digest;
paul718e3742002-12-13 20:15:29 +0000414 else
415 {
paul1eb8ef22005-04-07 07:30:20 +0000416 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000417 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000418 }
419
420 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000421 memset(&ctx, 0, sizeof(ctx));
422 MD5Init(&ctx);
423 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
424 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
425 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000426
427 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000428 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000429
430 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000431 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
432
paul37163d62003-02-03 18:40:56 +0000433 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000434 /* XXX size_t */
435 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
436 (u_long)stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000437
438 return OSPF_AUTH_MD5_SIZE;
439}
440
David Lamparter6b0655a2014-06-04 06:53:35 +0200441
paul4dadc292005-05-06 21:37:42 +0000442static int
paul718e3742002-12-13 20:15:29 +0000443ospf_ls_req_timer (struct thread *thread)
444{
445 struct ospf_neighbor *nbr;
446
447 nbr = THREAD_ARG (thread);
448 nbr->t_ls_req = NULL;
449
450 /* Send Link State Request. */
451 if (ospf_ls_request_count (nbr))
452 ospf_ls_req_send (nbr);
453
454 /* Set Link State Request retransmission timer. */
455 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
456
457 return 0;
458}
459
460void
461ospf_ls_req_event (struct ospf_neighbor *nbr)
462{
463 if (nbr->t_ls_req)
464 {
465 thread_cancel (nbr->t_ls_req);
466 nbr->t_ls_req = NULL;
467 }
468 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
469}
470
471/* Cyclic timer function. Fist registered in ospf_nbr_new () in
472 ospf_neighbor.c */
473int
474ospf_ls_upd_timer (struct thread *thread)
475{
476 struct ospf_neighbor *nbr;
477
478 nbr = THREAD_ARG (thread);
479 nbr->t_ls_upd = NULL;
480
481 /* Send Link State Update. */
482 if (ospf_ls_retransmit_count (nbr) > 0)
483 {
hasso52dc7ee2004-09-23 19:18:23 +0000484 struct list *update;
paul718e3742002-12-13 20:15:29 +0000485 struct ospf_lsdb *lsdb;
486 int i;
paul718e3742002-12-13 20:15:29 +0000487 int retransmit_interval;
488
paul718e3742002-12-13 20:15:29 +0000489 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
490
491 lsdb = &nbr->ls_rxmt;
492 update = list_new ();
493
494 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
495 {
496 struct route_table *table = lsdb->type[i].db;
497 struct route_node *rn;
498
499 for (rn = route_top (table); rn; rn = route_next (rn))
500 {
501 struct ospf_lsa *lsa;
502
503 if ((lsa = rn->info) != NULL)
504 /* Don't retransmit an LSA if we received it within
505 the last RxmtInterval seconds - this is to allow the
506 neighbour a chance to acknowledge the LSA as it may
507 have ben just received before the retransmit timer
508 fired. This is a small tweak to what is in the RFC,
509 but it will cut out out a lot of retransmit traffic
510 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000511 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000512 int2tv (retransmit_interval)) >= 0)
513 listnode_add (update, rn->info);
514 }
515 }
516
517 if (listcount (update) > 0)
518 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
519 list_delete (update);
520 }
521
522 /* Set LS Update retransmission timer. */
523 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
524
525 return 0;
526}
527
528int
529ospf_ls_ack_timer (struct thread *thread)
530{
531 struct ospf_interface *oi;
532
533 oi = THREAD_ARG (thread);
534 oi->t_ls_ack = NULL;
535
536 /* Send Link State Acknowledgment. */
537 if (listcount (oi->ls_ack) > 0)
538 ospf_ls_ack_send_delayed (oi);
539
540 /* Set LS Ack timer. */
541 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
542
543 return 0;
544}
545
paul0bfeca32004-09-24 08:07:54 +0000546#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000547static void
paul6a99f832004-09-27 12:56:30 +0000548ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000549 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000550 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000551{
552#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000553 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000554 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000555 int ret;
paul0bfeca32004-09-24 08:07:54 +0000556
557 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000558 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000559
560 /* we can but try.
561 *
562 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
563 * well as the IP_MF flag, making this all quite pointless.
564 *
565 * However, for a system on which IP_MF is left alone, and ip_id left
566 * alone or else which sets same ip_id for each fragment this might
567 * work, eg linux.
568 *
569 * XXX-TODO: It would be much nicer to have the kernel's use their
570 * existing fragmentation support to do this for us. Bugs/RFEs need to
571 * be raised against the various kernels.
572 */
573
574 /* set More Frag */
575 iph->ip_off |= IP_MF;
576
577 /* ip frag offset is expressed in units of 8byte words */
578 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
579
paul62d8e962004-11-02 20:26:45 +0000580 iovp = &msg->msg_iov[1];
581
paul0bfeca32004-09-24 08:07:54 +0000582 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
583 > maxdatasize )
584 {
585 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000586 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
587 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000588 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000589
paul18b12c32004-10-05 14:38:29 +0000590 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000591
paul6a99f832004-09-27 12:56:30 +0000592 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000593
paul18b12c32004-10-05 14:38:29 +0000594 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000595
596 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000597 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000598 " id %d, off %d, len %d, mtu %u failed with %s",
599 inet_ntoa (iph->ip_dst),
600 iph->ip_id,
601 iph->ip_off,
602 iph->ip_len,
603 mtu,
604 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000605
paul37ccfa32004-10-31 11:24:51 +0000606 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
607 {
ajs2a42e282004-12-08 18:43:03 +0000608 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000609 iph->ip_id, iph->ip_off, iph->ip_len,
610 inet_ntoa (iph->ip_dst));
611 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
612 {
ajs2a42e282004-12-08 18:43:03 +0000613 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000614 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000615 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000616 }
617 }
618
paul0bfeca32004-09-24 08:07:54 +0000619 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000620 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000621 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000622 }
623
624 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000625 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
626 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000627 iph->ip_off &= (~IP_MF);
628}
629#endif /* WANT_OSPF_WRITE_FRAGMENT */
630
ajs5dcbdf82005-03-29 16:13:49 +0000631static int
paul718e3742002-12-13 20:15:29 +0000632ospf_write (struct thread *thread)
633{
paul68980082003-03-25 05:07:42 +0000634 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000635 struct ospf_interface *oi;
636 struct ospf_packet *op;
637 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000638 struct ip iph;
639 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000640 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000641 u_char type;
642 int ret;
643 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000644 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000645#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000646 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000647#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000648 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000649#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000650
paul68980082003-03-25 05:07:42 +0000651 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000652
paul68980082003-03-25 05:07:42 +0000653 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000654 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000655 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000656 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000657
658#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000659 /* seed ipid static with low order bits of time */
660 if (ipid == 0)
661 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000662#endif /* WANT_OSPF_WRITE_FRAGMENT */
663
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000664 /* convenience - max OSPF data per packet,
665 * and reliability - not more data, than our
666 * socket can accept
667 */
668 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
669 sizeof (struct ip);
paul68b73392004-09-12 14:21:37 +0000670
paul718e3742002-12-13 20:15:29 +0000671 /* Get one packet from queue. */
672 op = ospf_fifo_head (oi->obuf);
673 assert (op);
674 assert (op->length >= OSPF_HEADER_SIZE);
675
paul68980082003-03-25 05:07:42 +0000676 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
677 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000678 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
679
paul718e3742002-12-13 20:15:29 +0000680 /* Rewrite the md5 signature & update the seq */
681 ospf_make_md5_digest (oi, op);
682
paul37ccfa32004-10-31 11:24:51 +0000683 /* Retrieve OSPF packet type. */
684 stream_set_getp (op->s, 1);
685 type = stream_getc (op->s);
686
paul68b73392004-09-12 14:21:37 +0000687 /* reset get pointer */
688 stream_set_getp (op->s, 0);
689
690 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000691 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000692
paul718e3742002-12-13 20:15:29 +0000693 sa_dst.sin_family = AF_INET;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000694#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +0000695 sa_dst.sin_len = sizeof(sa_dst);
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000696#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +0000697 sa_dst.sin_addr = op->dst;
698 sa_dst.sin_port = htons (0);
699
700 /* Set DONTROUTE flag if dst is unicast. */
701 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
702 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
703 flags = MSG_DONTROUTE;
704
paul68b73392004-09-12 14:21:37 +0000705 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
706 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000707 if ( sizeof (struct ip)
708 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000709 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
710
paul718e3742002-12-13 20:15:29 +0000711 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000712 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000713 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000714
David BÉRARD0150c9c2010-05-11 10:17:53 +0200715#if defined(__DragonFly__)
716 /*
717 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
718 */
719 iph.ip_len = htons(iph.ip_len);
720#endif
721
paul0bfeca32004-09-24 08:07:54 +0000722#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000723 /* XXX-MT: not thread-safe at all..
724 * XXX: this presumes this is only programme sending OSPF packets
725 * otherwise, no guarantee ipid will be unique
726 */
727 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000728#endif /* WANT_OSPF_WRITE_FRAGMENT */
729
paul718e3742002-12-13 20:15:29 +0000730 iph.ip_off = 0;
731 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
732 iph.ip_ttl = OSPF_VL_IP_TTL;
733 else
734 iph.ip_ttl = OSPF_IP_TTL;
735 iph.ip_p = IPPROTO_OSPFIGP;
736 iph.ip_sum = 0;
737 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
738 iph.ip_dst.s_addr = op->dst.s_addr;
739
740 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000741 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000742 msg.msg_namelen = sizeof (sa_dst);
743 msg.msg_iov = iov;
744 msg.msg_iovlen = 2;
745 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000746 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
747 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000748 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000749
750 /* Sadly we can not rely on kernels to fragment packets because of either
751 * IP_HDRINCL and/or multicast destination being set.
752 */
paul0bfeca32004-09-24 08:07:54 +0000753#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000754 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000755 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
756 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000757#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000758
759 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000760 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000761 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000762 sockopt_iphdrincl_swab_systoh (&iph);
Dinesh G Dutt1c063342014-09-30 13:04:45 -0700763 if (IS_DEBUG_OSPF_EVENT)
764 zlog_debug ("ospf_write to %s, "
765 "id %d, off %d, len %d, interface %s, mtu %u:",
766 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
767 oi->ifp->name, oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000768
769 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000770 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000771 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000772 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000773 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000774
paul718e3742002-12-13 20:15:29 +0000775 /* Show debug sending packet. */
776 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
777 {
778 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
779 {
ajs2a42e282004-12-08 18:43:03 +0000780 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000781 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000782 stream_set_getp (op->s, 0);
783 ospf_packet_dump (op->s);
784 }
785
ajs2a42e282004-12-08 18:43:03 +0000786 zlog_debug ("%s sent to [%s] via [%s].",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400787 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
paul718e3742002-12-13 20:15:29 +0000788 IF_NAME (oi));
789
790 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000791 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000792 }
793
794 /* Now delete packet from queue. */
795 ospf_packet_delete (oi);
796
Dinesh G Dutt1c063342014-09-30 13:04:45 -0700797 /* Move this interface to the tail of write_q to
798 serve everyone in a round robin fashion */
799 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000800 if (ospf_fifo_head (oi->obuf) == NULL)
801 {
802 oi->on_write_q = 0;
Dinesh G Dutt1c063342014-09-30 13:04:45 -0700803 }
804 else
805 {
806 listnode_add (ospf->oi_write_q, oi);
paul718e3742002-12-13 20:15:29 +0000807 }
808
809 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000810 if (!list_isempty (ospf->oi_write_q))
811 ospf->t_write =
812 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000813
814 return 0;
815}
816
817/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000818static void
paul718e3742002-12-13 20:15:29 +0000819ospf_hello (struct ip *iph, struct ospf_header *ospfh,
820 struct stream * s, struct ospf_interface *oi, int size)
821{
822 struct ospf_hello *hello;
823 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000824 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000825 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000826
827 /* increment statistics. */
828 oi->hello_in++;
829
830 hello = (struct ospf_hello *) STREAM_PNT (s);
831
832 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000833 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000834 {
835 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
836 {
ajs2a42e282004-12-08 18:43:03 +0000837 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000838 "dropping.",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400839 LOOKUP (ospf_packet_type_str, ospfh->type),
pauld3241812003-09-29 12:42:39 +0000840 inet_ntoa (iph->ip_src));
841 }
842 return;
843 }
paul718e3742002-12-13 20:15:29 +0000844
paul718e3742002-12-13 20:15:29 +0000845 /* get neighbor prefix. */
846 p.family = AF_INET;
847 p.prefixlen = ip_masklen (hello->network_mask);
848 p.u.prefix4 = iph->ip_src;
849
850 /* Compare network mask. */
851 /* Checking is ignored for Point-to-Point and Virtual link. */
852 if (oi->type != OSPF_IFTYPE_POINTOPOINT
853 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
854 if (oi->address->prefixlen != p.prefixlen)
855 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000856 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
857 inet_ntoa(ospfh->router_id), IF_NAME(oi),
858 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000859 return;
860 }
861
paul718e3742002-12-13 20:15:29 +0000862 /* Compare Router Dead Interval. */
863 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
864 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000865 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
866 "(expected %u, but received %u).",
867 inet_ntoa(ospfh->router_id),
868 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000869 return;
870 }
871
paulf9ad9372005-10-21 00:45:17 +0000872 /* Compare Hello Interval - ignored if fast-hellos are set. */
873 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
874 {
875 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
876 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000877 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
878 "(expected %u, but received %u).",
879 inet_ntoa(ospfh->router_id),
880 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000881 return;
882 }
883 }
884
paul718e3742002-12-13 20:15:29 +0000885 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000886 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000887 inet_ntoa (ospfh->router_id),
888 ospf_options_dump (hello->options));
889
890 /* Compare options. */
891#define REJECT_IF_TBIT_ON 1 /* XXX */
892#ifdef REJECT_IF_TBIT_ON
893 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
894 {
895 /*
896 * This router does not support non-zero TOS.
897 * Drop this Hello packet not to establish neighbor relationship.
898 */
899 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
900 inet_ntoa (ospfh->router_id));
901 return;
902 }
903#endif /* REJECT_IF_TBIT_ON */
904
905#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000906 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000907 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
908 {
909 /*
910 * This router does know the correct usage of O-bit
911 * the bit should be set in DD packet only.
912 */
913 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
914 inet_ntoa (ospfh->router_id));
915#ifdef STRICT_OBIT_USAGE_CHECK
916 return; /* Reject this packet. */
917#else /* STRICT_OBIT_USAGE_CHECK */
918 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
919#endif /* STRICT_OBIT_USAGE_CHECK */
920 }
921#endif /* HAVE_OPAQUE_LSA */
922
923 /* new for NSSA is to ensure that NP is on and E is off */
924
paul718e3742002-12-13 20:15:29 +0000925 if (oi->area->external_routing == OSPF_AREA_NSSA)
926 {
927 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
928 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
929 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
930 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
931 {
932 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
933 return;
934 }
935 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000936 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000937 }
938 else
paul718e3742002-12-13 20:15:29 +0000939 /* The setting of the E-bit found in the Hello Packet's Options
940 field must match this area's ExternalRoutingCapability A
941 mismatch causes processing to stop and the packet to be
942 dropped. The setting of the rest of the bits in the Hello
943 Packet's Options field should be ignored. */
944 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
945 CHECK_FLAG (hello->options, OSPF_OPTION_E))
946 {
ajs3aa8d5f2004-12-11 18:00:06 +0000947 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
948 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000949 return;
950 }
paul718e3742002-12-13 20:15:29 +0000951
pauld3f0d622004-05-05 15:27:15 +0000952 /* get neighbour struct */
953 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
954
955 /* neighbour must be valid, ospf_nbr_get creates if none existed */
956 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000957
958 old_state = nbr->state;
959
960 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000961 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000962
963 /* RFC2328 Section 9.5.1
964 If the router is not eligible to become Designated Router,
965 (snip) It must also send an Hello Packet in reply to an
966 Hello Packet received from any eligible neighbor (other than
967 the current Designated Router and Backup Designated Router). */
968 if (oi->type == OSPF_IFTYPE_NBMA)
969 if (PRIORITY(oi) == 0 && hello->priority > 0
970 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
971 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
972 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
973 OSPF_HELLO_REPLY_DELAY);
974
975 /* on NBMA network type, it happens to receive bidirectional Hello packet
976 without advance 1-Way Received event.
977 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
978 if (oi->type == OSPF_IFTYPE_NBMA &&
979 (old_state == NSM_Down || old_state == NSM_Attempt))
980 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000981 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000982 nbr->priority = hello->priority;
983 nbr->d_router = hello->d_router;
984 nbr->bd_router = hello->bd_router;
985 return;
986 }
987
paul68980082003-03-25 05:07:42 +0000988 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000989 size - OSPF_HELLO_MIN_SIZE))
990 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000991 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000992 nbr->options |= hello->options;
993 }
994 else
995 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000996 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000997 /* Set neighbor information. */
998 nbr->priority = hello->priority;
999 nbr->d_router = hello->d_router;
1000 nbr->bd_router = hello->bd_router;
1001 return;
1002 }
1003
1004 /* If neighbor itself declares DR and no BDR exists,
1005 cause event BackupSeen */
1006 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
1007 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
1008 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
1009
1010 /* neighbor itself declares BDR. */
1011 if (oi->state == ISM_Waiting &&
1012 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
1013 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
1014
1015 /* had not previously. */
1016 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
1017 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
1018 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
1019 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
1020 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1021
1022 /* had not previously. */
1023 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
1024 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
1025 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
1026 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
1027 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1028
1029 /* Neighbor priority check. */
1030 if (nbr->priority >= 0 && nbr->priority != hello->priority)
1031 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1032
1033 /* Set neighbor information. */
1034 nbr->priority = hello->priority;
1035 nbr->d_router = hello->d_router;
1036 nbr->bd_router = hello->bd_router;
1037}
1038
1039/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +00001040static void
paul718e3742002-12-13 20:15:29 +00001041ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1042 struct ospf_db_desc *dd)
1043{
1044 nbr->last_recv.flags = dd->flags;
1045 nbr->last_recv.options = dd->options;
1046 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1047}
1048
1049/* Process rest of DD packet. */
1050static void
1051ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1052 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1053 u_int16_t size)
1054{
1055 struct ospf_lsa *new, *find;
1056 struct lsa_header *lsah;
1057
paul9985f832005-02-09 15:51:56 +00001058 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001059 for (size -= OSPF_DB_DESC_MIN_SIZE;
1060 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1061 {
1062 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001063 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001064
1065 /* Unknown LS type. */
1066 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1067 {
ajsbec595a2004-11-30 22:38:43 +00001068 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001069 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1070 return;
1071 }
1072
1073#ifdef HAVE_OPAQUE_LSA
1074 if (IS_OPAQUE_LSA (lsah->type)
1075 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1076 {
1077 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1078 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1079 return;
1080 }
1081#endif /* HAVE_OPAQUE_LSA */
1082
1083 switch (lsah->type)
1084 {
1085 case OSPF_AS_EXTERNAL_LSA:
1086#ifdef HAVE_OPAQUE_LSA
1087 case OSPF_OPAQUE_AS_LSA:
1088#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001089 /* Check for stub area. Reject if AS-External from stub but
1090 allow if from NSSA. */
1091 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001092 {
1093 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1094 lsah->type, inet_ntoa (lsah->id),
1095 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1096 "STUB" : "NSSA");
1097 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1098 return;
1099 }
1100 break;
1101 default:
1102 break;
1103 }
1104
1105 /* Create LS-request object. */
1106 new = ospf_ls_request_new (lsah);
1107
1108 /* Lookup received LSA, then add LS request list. */
1109 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001110
1111 /* ospf_lsa_more_recent is fine with NULL pointers */
1112 switch (ospf_lsa_more_recent (find, new))
1113 {
1114 case -1:
1115 /* Neighbour has a more recent LSA, we must request it */
1116 ospf_ls_request_add (nbr, new);
1117 case 0:
1118 /* If we have a copy of this LSA, it's either less recent
1119 * and we're requesting it from neighbour (the case above), or
1120 * it's as recent and we both have same copy (this case).
1121 *
1122 * In neither of these two cases is there any point in
1123 * describing our copy of the LSA to the neighbour in a
1124 * DB-Summary packet, if we're still intending to do so.
1125 *
1126 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1127 * backward compatible optimisation to OSPF DB Exchange /
1128 * DB Description process implemented here.
1129 */
1130 if (find)
1131 ospf_lsdb_delete (&nbr->db_sum, find);
1132 ospf_lsa_discard (new);
1133 break;
1134 default:
1135 /* We have the more recent copy, nothing specific to do:
1136 * - no need to request neighbours stale copy
1137 * - must leave DB summary list copy alone
1138 */
1139 if (IS_DEBUG_OSPF_EVENT)
1140 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1141 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1142 ospf_lsa_discard (new);
1143 }
paul718e3742002-12-13 20:15:29 +00001144 }
1145
1146 /* Master */
1147 if (IS_SET_DD_MS (nbr->dd_flags))
1148 {
1149 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001150
1151 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001152 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1153 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1154 else
paul718e3742002-12-13 20:15:29 +00001155 ospf_db_desc_send (nbr);
1156 }
1157 /* Slave */
1158 else
1159 {
1160 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1161
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001162 /* Send DD packet in reply.
1163 *
1164 * Must be done to acknowledge the Master's DD, regardless of
1165 * whether we have more LSAs ourselves to describe.
1166 *
1167 * This function will clear the 'More' bit, if after this DD
1168 * we have no more LSAs to describe to the master..
1169 */
paul718e3742002-12-13 20:15:29 +00001170 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001171
1172 /* Slave can raise ExchangeDone now, if master is also done */
1173 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1174 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001175 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001176
paul718e3742002-12-13 20:15:29 +00001177 /* Save received neighbor values from DD. */
1178 ospf_db_desc_save_current (nbr, dd);
1179}
1180
paul4dadc292005-05-06 21:37:42 +00001181static int
paul718e3742002-12-13 20:15:29 +00001182ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1183{
1184 /* Is DD duplicated? */
1185 if (dd->options == nbr->last_recv.options &&
1186 dd->flags == nbr->last_recv.flags &&
1187 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1188 return 1;
1189
1190 return 0;
1191}
1192
1193/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001194static void
paul718e3742002-12-13 20:15:29 +00001195ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1196 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1197{
1198 struct ospf_db_desc *dd;
1199 struct ospf_neighbor *nbr;
1200
1201 /* Increment statistics. */
1202 oi->db_desc_in++;
1203
1204 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001205
pauld3f0d622004-05-05 15:27:15 +00001206 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001207 if (nbr == NULL)
1208 {
1209 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1210 inet_ntoa (ospfh->router_id));
1211 return;
1212 }
1213
1214 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001215 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1216 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001217 {
ajs3aa8d5f2004-12-11 18:00:06 +00001218 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1219 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1220 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001221 return;
1222 }
1223
pauld363df22003-06-19 00:26:34 +00001224 /*
1225 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1226 * required. In fact at least JunOS sends DD packets with P bit clear.
1227 * Until proper solution is developped, this hack should help.
1228 *
1229 * Update: According to the RFCs, N bit is specified /only/ for Hello
1230 * options, unfortunately its use in DD options is not specified. Hence some
1231 * implementations follow E-bit semantics and set it in DD options, and some
1232 * treat it as unspecified and hence follow the directive "default for
1233 * options is clear", ie unset.
1234 *
1235 * Reset the flag, as ospfd follows E-bit semantics.
1236 */
1237 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1238 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1239 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1240 {
1241 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001242 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001243 inet_ntoa (nbr->router_id) );
1244 SET_FLAG (dd->options, OSPF_OPTION_NP);
1245 }
pauld363df22003-06-19 00:26:34 +00001246
paul718e3742002-12-13 20:15:29 +00001247#ifdef REJECT_IF_TBIT_ON
1248 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1249 {
1250 /*
1251 * In Hello protocol, optional capability must have checked
1252 * to prevent this T-bit enabled router be my neighbor.
1253 */
1254 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1255 return;
1256 }
1257#endif /* REJECT_IF_TBIT_ON */
1258
1259#ifdef HAVE_OPAQUE_LSA
1260 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001261 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001262 {
1263 /*
1264 * This node is not configured to handle O-bit, for now.
1265 * Clear it to ignore unsupported capability proposed by neighbor.
1266 */
1267 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1268 }
1269#endif /* HAVE_OPAQUE_LSA */
1270
Paul Jakma57c5c652010-01-07 06:12:53 +00001271 /* Add event to thread. */
1272 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1273
paul718e3742002-12-13 20:15:29 +00001274 /* Process DD packet by neighbor status. */
1275 switch (nbr->state)
1276 {
1277 case NSM_Down:
1278 case NSM_Attempt:
1279 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001280 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001281 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001282 LOOKUP (ospf_nsm_state_msg, nbr->state));
1283 break;
1284 case NSM_Init:
1285 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1286 /* If the new state is ExStart, the processing of the current
1287 packet should then continue in this new state by falling
1288 through to case ExStart below. */
1289 if (nbr->state != NSM_ExStart)
1290 break;
1291 case NSM_ExStart:
1292 /* Initial DBD */
1293 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1294 (size == OSPF_DB_DESC_MIN_SIZE))
1295 {
paul68980082003-03-25 05:07:42 +00001296 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001297 {
1298 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001299 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001300 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001301 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001302
1303 /* Reset I/MS */
1304 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001305 }
1306 else
1307 {
1308 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001309 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001310 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001311 break;
1312 }
1313 }
1314 /* Ack from the Slave */
1315 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1316 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001317 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001318 {
ajs17eaa722004-12-29 21:04:48 +00001319 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001320 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001321 /* Reset I, leaving MS */
1322 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001323 }
1324 else
1325 {
ajs3aa8d5f2004-12-11 18:00:06 +00001326 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1327 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001328 break;
1329 }
1330
1331 /* This is where the real Options are saved */
1332 nbr->options = dd->options;
1333
1334#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001335 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001336 {
1337 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001338 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001339 inet_ntoa (nbr->router_id),
1340 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1341
1342 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1343 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1344 {
paul6d452762005-11-03 11:15:44 +00001345 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1346 "Opaque-LSAs cannot be reliably advertised "
1347 "in this network.",
1348 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001349 /* This situation is undesirable, but not a real error. */
1350 }
1351 }
1352#endif /* HAVE_OPAQUE_LSA */
1353
1354 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1355
1356 /* continue processing rest of packet. */
1357 ospf_db_desc_proc (s, oi, nbr, dd, size);
1358 break;
1359 case NSM_Exchange:
1360 if (ospf_db_desc_is_dup (dd, nbr))
1361 {
1362 if (IS_SET_DD_MS (nbr->dd_flags))
1363 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001364 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001365 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001366 else
1367 /* Slave: cause to retransmit the last Database Description. */
1368 {
paul6d452762005-11-03 11:15:44 +00001369 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001370 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001371 ospf_db_desc_resend (nbr);
1372 }
1373 break;
1374 }
1375
1376 /* Otherwise DD packet should be checked. */
1377 /* Check Master/Slave bit mismatch */
1378 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1379 {
ajs3aa8d5f2004-12-11 18:00:06 +00001380 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1381 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001382 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1383 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001384 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001385 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001386 break;
1387 }
1388
1389 /* Check initialize bit is set. */
1390 if (IS_SET_DD_I (dd->flags))
1391 {
paul6d452762005-11-03 11:15:44 +00001392 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001393 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001394 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1395 break;
1396 }
1397
1398 /* Check DD Options. */
1399 if (dd->options != nbr->options)
1400 {
1401#ifdef ORIGINAL_CODING
1402 /* Save the new options for debugging */
1403 nbr->options = dd->options;
1404#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001405 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1406 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001407 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1408 break;
1409 }
1410
1411 /* Check DD sequence number. */
1412 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1413 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1414 (!IS_SET_DD_MS (nbr->dd_flags) &&
1415 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1416 {
ajs3aa8d5f2004-12-11 18:00:06 +00001417 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1418 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001419 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1420 break;
1421 }
1422
1423 /* Continue processing rest of packet. */
1424 ospf_db_desc_proc (s, oi, nbr, dd, size);
1425 break;
1426 case NSM_Loading:
1427 case NSM_Full:
1428 if (ospf_db_desc_is_dup (dd, nbr))
1429 {
1430 if (IS_SET_DD_MS (nbr->dd_flags))
1431 {
1432 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001433 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1434 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001435 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001436 break;
1437 }
1438 else
1439 {
1440 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001441 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001442 t = tv_sub (now, nbr->last_send_ts);
1443 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1444 {
1445 /* In states Loading and Full the slave must resend
1446 its last Database Description packet in response to
1447 duplicate Database Description packets received
1448 from the master. For this reason the slave must
1449 wait RouterDeadInterval seconds before freeing the
1450 last Database Description packet. Reception of a
1451 Database Description packet from the master after
1452 this interval will generate a SeqNumberMismatch
1453 neighbor event. RFC2328 Section 10.8 */
1454 ospf_db_desc_resend (nbr);
1455 break;
1456 }
1457 }
1458 }
1459
1460 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1461 break;
1462 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001463 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1464 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001465 break;
1466 }
1467}
1468
1469#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1470
1471/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001472static void
paul718e3742002-12-13 20:15:29 +00001473ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1474 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1475{
1476 struct ospf_neighbor *nbr;
1477 u_int32_t ls_type;
1478 struct in_addr ls_id;
1479 struct in_addr adv_router;
1480 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001481 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001482 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001483
1484 /* Increment statistics. */
1485 oi->ls_req_in++;
1486
pauld3f0d622004-05-05 15:27:15 +00001487 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001488 if (nbr == NULL)
1489 {
1490 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1491 inet_ntoa (ospfh->router_id));
1492 return;
1493 }
1494
Paul Jakma57c5c652010-01-07 06:12:53 +00001495 /* Add event to thread. */
1496 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1497
paul718e3742002-12-13 20:15:29 +00001498 /* Neighbor State should be Exchange or later. */
1499 if (nbr->state != NSM_Exchange &&
1500 nbr->state != NSM_Loading &&
1501 nbr->state != NSM_Full)
1502 {
ajsbec595a2004-11-30 22:38:43 +00001503 zlog_warn ("Link State Request received from %s: "
1504 "Neighbor state is %s, packet discarded.",
1505 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001506 LOOKUP (ospf_nsm_state_msg, nbr->state));
1507 return;
1508 }
1509
1510 /* Send Link State Update for ALL requested LSAs. */
1511 ls_upd = list_new ();
1512 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1513
1514 while (size >= OSPF_LSA_KEY_SIZE)
1515 {
1516 /* Get one slice of Link State Request. */
1517 ls_type = stream_getl (s);
1518 ls_id.s_addr = stream_get_ipv4 (s);
1519 adv_router.s_addr = stream_get_ipv4 (s);
1520
1521 /* Verify LSA type. */
1522 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1523 {
1524 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1525 list_delete (ls_upd);
1526 return;
1527 }
1528
1529 /* Search proper LSA in LSDB. */
1530 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1531 if (find == NULL)
1532 {
1533 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1534 list_delete (ls_upd);
1535 return;
1536 }
1537
gdt86f1fd92005-01-10 14:20:43 +00001538 /* Packet overflows MTU size, send immediately. */
1539 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001540 {
1541 if (oi->type == OSPF_IFTYPE_NBMA)
1542 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1543 else
1544 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1545
1546 /* Only remove list contents. Keep ls_upd. */
1547 list_delete_all_node (ls_upd);
1548
1549 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1550 }
1551
1552 /* Append LSA to update list. */
1553 listnode_add (ls_upd, find);
1554 length += ntohs (find->data->length);
1555
1556 size -= OSPF_LSA_KEY_SIZE;
1557 }
1558
1559 /* Send rest of Link State Update. */
1560 if (listcount (ls_upd) > 0)
1561 {
1562 if (oi->type == OSPF_IFTYPE_NBMA)
1563 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1564 else
1565 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1566
1567 list_delete (ls_upd);
1568 }
1569 else
1570 list_free (ls_upd);
1571}
1572
1573/* Get the list of LSAs from Link State Update packet.
1574 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001575static struct list *
paul718e3742002-12-13 20:15:29 +00001576ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1577 struct ospf_interface *oi, size_t size)
1578{
1579 u_int16_t count, sum;
1580 u_int32_t length;
1581 struct lsa_header *lsah;
1582 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001583 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001584
1585 lsas = list_new ();
1586
1587 count = stream_getl (s);
1588 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1589
1590 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001591 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001592 {
1593 lsah = (struct lsa_header *) STREAM_PNT (s);
1594 length = ntohs (lsah->length);
1595
1596 if (length > size)
1597 {
1598 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1599 break;
1600 }
1601
1602 /* Validate the LSA's LS checksum. */
1603 sum = lsah->checksum;
JR Riversd8a4e422012-09-13 17:17:36 +00001604 if (! ospf_lsa_checksum_valid (lsah))
paul718e3742002-12-13 20:15:29 +00001605 {
Jaroslav Fojtik223da1a2011-12-11 18:22:16 +04001606 /* (bug #685) more details in a one-line message make it possible
1607 * to identify problem source on the one hand and to have a better
1608 * chance to compress repeated messages in syslog on the other */
1609 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1610 sum, lsah->checksum, inet_ntoa (lsah->id),
1611 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1612 inet_ntoa (lsah->adv_router));
paul718e3742002-12-13 20:15:29 +00001613 continue;
1614 }
1615
1616 /* Examine the LSA's LS type. */
1617 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1618 {
1619 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1620 continue;
1621 }
1622
1623 /*
1624 * What if the received LSA's age is greater than MaxAge?
1625 * Treat it as a MaxAge case -- endo.
1626 */
1627 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1628 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1629
1630#ifdef HAVE_OPAQUE_LSA
1631 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1632 {
1633#ifdef STRICT_OBIT_USAGE_CHECK
1634 if ((IS_OPAQUE_LSA(lsah->type) &&
1635 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1636 || (! IS_OPAQUE_LSA(lsah->type) &&
1637 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1638 {
1639 /*
1640 * This neighbor must know the exact usage of O-bit;
1641 * the bit will be set in Type-9,10,11 LSAs only.
1642 */
1643 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1644 continue;
1645 }
1646#endif /* STRICT_OBIT_USAGE_CHECK */
1647
1648 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1649 if (lsah->type == OSPF_OPAQUE_AS_LSA
1650 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1651 {
1652 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001653 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 +00001654 continue;
1655 }
1656 }
1657 else if (IS_OPAQUE_LSA(lsah->type))
1658 {
1659 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1660 continue;
1661 }
1662#endif /* HAVE_OPAQUE_LSA */
1663
1664 /* Create OSPF LSA instance. */
1665 lsa = ospf_lsa_new ();
1666
1667 /* We may wish to put some error checking if type NSSA comes in
1668 and area not in NSSA mode */
1669 switch (lsah->type)
1670 {
1671 case OSPF_AS_EXTERNAL_LSA:
1672#ifdef HAVE_OPAQUE_LSA
1673 case OSPF_OPAQUE_AS_LSA:
Christian Franke58952492013-02-20 10:00:53 +00001674#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001675 lsa->area = NULL;
1676 break;
Christian Franke58952492013-02-20 10:00:53 +00001677#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001678 case OSPF_OPAQUE_LINK_LSA:
1679 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1680 /* Fallthrough */
1681#endif /* HAVE_OPAQUE_LSA */
1682 default:
1683 lsa->area = oi->area;
1684 break;
1685 }
1686
1687 lsa->data = ospf_lsa_data_new (length);
1688 memcpy (lsa->data, lsah, length);
1689
1690 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001691 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001692 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1693 listnode_add (lsas, lsa);
1694 }
1695
1696 return lsas;
1697}
1698
1699/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001700static void
hasso52dc7ee2004-09-23 19:18:23 +00001701ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001702{
paul1eb8ef22005-04-07 07:30:20 +00001703 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001704 struct ospf_lsa *lsa;
1705
paul1eb8ef22005-04-07 07:30:20 +00001706 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1707 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001708
1709 list_delete (lsas);
1710}
1711
1712/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001713static void
paul718e3742002-12-13 20:15:29 +00001714ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1715 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1716{
1717 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001718 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001719 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001720 struct ospf_lsa *lsa = NULL;
1721 /* unsigned long ls_req_found = 0; */
1722
1723 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1724
1725 /* Increment statistics. */
1726 oi->ls_upd_in++;
1727
1728 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001729 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001730 if (nbr == NULL)
1731 {
1732 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1733 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1734 return;
1735 }
1736
Paul Jakma57c5c652010-01-07 06:12:53 +00001737 /* Add event to thread. */
1738 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1739
paul718e3742002-12-13 20:15:29 +00001740 /* Check neighbor state. */
1741 if (nbr->state < NSM_Exchange)
1742 {
ajs3aa8d5f2004-12-11 18:00:06 +00001743 zlog_warn ("Link State Update: "
1744 "Neighbor[%s] state %s is less than Exchange",
1745 inet_ntoa (ospfh->router_id),
1746 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001747 return;
1748 }
1749
1750 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1751 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1752 * of section 13.
1753 */
1754 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1755
1756#ifdef HAVE_OPAQUE_LSA
1757 /*
paul718e3742002-12-13 20:15:29 +00001758 * If self-originated Opaque-LSAs that have flooded before restart
1759 * are contained in the received LSUpd message, corresponding LSReq
1760 * messages to be sent may have to be modified.
1761 * To eliminate possible race conditions such that flushing and normal
1762 * updating for the same LSA would take place alternately, this trick
1763 * must be done before entering to the loop below.
1764 */
paul69310a62005-05-11 18:09:59 +00001765 /* XXX: Why is this Opaque specific? Either our core code is deficient
1766 * and this should be fixed generally, or Opaque is inventing strawman
1767 * problems */
paul718e3742002-12-13 20:15:29 +00001768 ospf_opaque_adjust_lsreq (nbr, lsas);
1769#endif /* HAVE_OPAQUE_LSA */
1770
1771#define DISCARD_LSA(L,N) {\
1772 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001773 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 +00001774 ospf_lsa_discard (L); \
1775 continue; }
1776
Andrew Certainf92c57f2012-12-04 13:29:21 -08001777 /* Process each LSA received in the one packet.
1778 *
1779 * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
Andrew Certain0798cee2012-12-04 13:43:42 -08001780 * text below are from the steps in RFC 2328, Section 13.
Andrew Certainf92c57f2012-12-04 13:29:21 -08001781 */
paul1eb8ef22005-04-07 07:30:20 +00001782 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001783 {
1784 struct ospf_lsa *ls_ret, *current;
1785 int ret = 1;
1786
paul718e3742002-12-13 20:15:29 +00001787 if (IS_DEBUG_OSPF_NSSA)
1788 {
1789 char buf1[INET_ADDRSTRLEN];
1790 char buf2[INET_ADDRSTRLEN];
1791 char buf3[INET_ADDRSTRLEN];
1792
ajs2a42e282004-12-08 18:43:03 +00001793 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001794 lsa->data->type,
1795 inet_ntop (AF_INET, &ospfh->router_id,
1796 buf1, INET_ADDRSTRLEN),
1797 inet_ntop (AF_INET, &lsa->data->id,
1798 buf2, INET_ADDRSTRLEN),
1799 inet_ntop (AF_INET, &lsa->data->adv_router,
1800 buf3, INET_ADDRSTRLEN));
1801 }
paul718e3742002-12-13 20:15:29 +00001802
1803 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1804
Andrew Certainf92c57f2012-12-04 13:29:21 -08001805 /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
paul718e3742002-12-13 20:15:29 +00001806
Andrew Certainf92c57f2012-12-04 13:29:21 -08001807 /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
paul718e3742002-12-13 20:15:29 +00001808
Andrew Certainf92c57f2012-12-04 13:29:21 -08001809 /* (3) Do not take in AS External LSAs if we are a stub or NSSA. */
paul718e3742002-12-13 20:15:29 +00001810
1811 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1812
1813 /* Do take in Type-7's if we are an NSSA */
1814
1815 /* If we are also an ABR, later translate them to a Type-5 packet */
1816
1817 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1818 translate them to a separate Type-5 packet. */
1819
1820 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1821 /* Reject from STUB or NSSA */
1822 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1823 {
paul718e3742002-12-13 20:15:29 +00001824 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001825 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001826 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001827 }
1828
paul718e3742002-12-13 20:15:29 +00001829 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1830 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1831 {
paul718e3742002-12-13 20:15:29 +00001832 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001833 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001834 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001835 }
paul718e3742002-12-13 20:15:29 +00001836
David Lamparter23cd8fb2013-08-02 07:27:53 +00001837 /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */
1838 if (lsa->data->type == OSPF_ROUTER_LSA)
1839 if (!IPV4_ADDR_SAME(&lsa->data->id, &lsa->data->adv_router))
1840 {
1841 char buf1[INET_ADDRSTRLEN];
1842 char buf2[INET_ADDRSTRLEN];
1843 char buf3[INET_ADDRSTRLEN];
1844
1845 zlog_err("Incoming Router-LSA from %s with "
1846 "Adv-ID[%s] != LS-ID[%s]",
1847 inet_ntop (AF_INET, &ospfh->router_id,
1848 buf1, INET_ADDRSTRLEN),
1849 inet_ntop (AF_INET, &lsa->data->id,
1850 buf2, INET_ADDRSTRLEN),
1851 inet_ntop (AF_INET, &lsa->data->adv_router,
1852 buf3, INET_ADDRSTRLEN));
1853 zlog_err("OSPF domain compromised by attack or corruption. "
1854 "Verify correct operation of -ALL- OSPF routers.");
1855 DISCARD_LSA (lsa, 0);
1856 }
1857
paul718e3742002-12-13 20:15:29 +00001858 /* Find the LSA in the current database. */
1859
1860 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1861
Andrew Certainf92c57f2012-12-04 13:29:21 -08001862 /* (4) If the LSA's LS age is equal to MaxAge, and there is currently
paul718e3742002-12-13 20:15:29 +00001863 no instance of the LSA in the router's link state database,
1864 and none of router's neighbors are in states Exchange or Loading,
Andrew Certainf92c57f2012-12-04 13:29:21 -08001865 then take the following actions: */
paul718e3742002-12-13 20:15:29 +00001866
1867 if (IS_LSA_MAXAGE (lsa) && !current &&
Christian Franke4c14b7f2013-02-20 10:00:54 +00001868 ospf_check_nbr_status(oi->ospf))
paul718e3742002-12-13 20:15:29 +00001869 {
Andrew Certainf92c57f2012-12-04 13:29:21 -08001870 /* (4a) Response Link State Acknowledgment. */
paul718e3742002-12-13 20:15:29 +00001871 ospf_ls_ack_send (nbr, lsa);
1872
Andrew Certainf92c57f2012-12-04 13:29:21 -08001873 /* (4b) Discard LSA. */
Ayan Banerjeefaf98752012-12-04 10:49:12 -08001874 if (IS_DEBUG_OSPF (lsa, LSA))
1875 {
1876 zlog_debug ("Link State Update[%s]: LS age is equal to MaxAge.",
1877 dump_lsa_key(lsa));
1878 }
paul718e3742002-12-13 20:15:29 +00001879 DISCARD_LSA (lsa, 3);
1880 }
1881
1882#ifdef HAVE_OPAQUE_LSA
1883 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001884 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001885 {
1886 /*
1887 * Even if initial flushing seems to be completed, there might
1888 * be a case that self-originated LSA with MaxAge still remain
1889 * in the routing domain.
1890 * Just send an LSAck message to cease retransmission.
1891 */
1892 if (IS_LSA_MAXAGE (lsa))
1893 {
1894 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1895 ospf_ls_ack_send (nbr, lsa);
1896 ospf_lsa_discard (lsa);
1897
1898 if (current != NULL && ! IS_LSA_MAXAGE (current))
1899 ospf_opaque_lsa_refresh_schedule (current);
1900 continue;
1901 }
1902
1903 /*
1904 * If an instance of self-originated Opaque-LSA is not found
1905 * in the LSDB, there are some possible cases here.
1906 *
1907 * 1) This node lost opaque-capability after restart.
1908 * 2) Else, a part of opaque-type is no more supported.
1909 * 3) Else, a part of opaque-id is no more supported.
1910 *
1911 * Anyway, it is still this node's responsibility to flush it.
1912 * Otherwise, the LSA instance remains in the routing domain
1913 * until its age reaches to MaxAge.
1914 */
paul69310a62005-05-11 18:09:59 +00001915 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001916 if (current == NULL)
1917 {
1918 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001919 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1920 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001921
1922 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001923
1924 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1925 ospf_ls_ack_send (nbr, lsa);
1926
paul718e3742002-12-13 20:15:29 +00001927 continue;
1928 }
1929 }
1930#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001931
hassocb05eb22004-02-11 21:10:19 +00001932 /* It might be happen that received LSA is self-originated network LSA, but
Andrew Certainf92c57f2012-12-04 13:29:21 -08001933 * router ID is changed. So, we should check if LSA is a network-LSA whose
hassocb05eb22004-02-11 21:10:19 +00001934 * Link State ID is one of the router's own IP interface addresses but whose
1935 * Advertising Router is not equal to the router's own Router ID
1936 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1937 */
1938
1939 if(lsa->data->type == OSPF_NETWORK_LSA)
1940 {
paul1eb8ef22005-04-07 07:30:20 +00001941 struct listnode *oinode, *oinnode;
1942 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001943 int Flag = 0;
1944
paul1eb8ef22005-04-07 07:30:20 +00001945 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001946 {
hassocb05eb22004-02-11 21:10:19 +00001947 if(out_if == NULL)
1948 break;
1949
1950 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1951 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1952 {
1953 if(out_if->network_lsa_self)
1954 {
1955 ospf_lsa_flush_area(lsa,out_if->area);
1956 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001957 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001958 lsa, (int) lsa->data->type);
1959 ospf_lsa_discard (lsa);
1960 Flag = 1;
1961 }
1962 break;
1963 }
1964 }
1965 if(Flag)
1966 continue;
1967 }
paul718e3742002-12-13 20:15:29 +00001968
1969 /* (5) Find the instance of this LSA that is currently contained
1970 in the router's link state database. If there is no
1971 database copy, or the received LSA is more recent than
Andrew Certainf92c57f2012-12-04 13:29:21 -08001972 the database copy the following steps must be performed.
1973 (The sub steps from RFC 2328 section 13 step (5) will be performed in
1974 ospf_flood() ) */
paul718e3742002-12-13 20:15:29 +00001975
1976 if (current == NULL ||
1977 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1978 {
1979 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001980 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001981 DISCARD_LSA (lsa, 4);
1982 continue;
1983 }
1984
1985 /* (6) Else, If there is an instance of the LSA on the sending
1986 neighbor's Link state request list, an error has occurred in
1987 the Database Exchange process. In this case, restart the
1988 Database Exchange process by generating the neighbor event
1989 BadLSReq for the sending neighbor and stop processing the
1990 Link State Update packet. */
1991
1992 if (ospf_ls_request_lookup (nbr, lsa))
1993 {
1994 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001995 zlog_warn("LSA[%s] instance exists on Link state request list",
1996 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001997
1998 /* Clean list of LSAs. */
1999 ospf_upd_list_clean (lsas);
2000 /* this lsa is not on lsas list already. */
2001 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00002002 return;
2003 }
2004
2005 /* If the received LSA is the same instance as the database copy
2006 (i.e., neither one is more recent) the following two steps
2007 should be performed: */
2008
2009 if (ret == 0)
2010 {
2011 /* If the LSA is listed in the Link state retransmission list
2012 for the receiving adjacency, the router itself is expecting
2013 an acknowledgment for this LSA. The router should treat the
2014 received LSA as an acknowledgment by removing the LSA from
2015 the Link state retransmission list. This is termed an
2016 "implied acknowledgment". */
2017
2018 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
2019
2020 if (ls_ret != NULL)
2021 {
2022 ospf_ls_retransmit_delete (nbr, ls_ret);
2023
2024 /* Delayed acknowledgment sent if advertisement received
2025 from Designated Router, otherwise do nothing. */
2026 if (oi->state == ISM_Backup)
2027 if (NBR_IS_DR (nbr))
2028 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
2029
2030 DISCARD_LSA (lsa, 5);
2031 }
2032 else
2033 /* Acknowledge the receipt of the LSA by sending a
2034 Link State Acknowledgment packet back out the receiving
2035 interface. */
2036 {
2037 ospf_ls_ack_send (nbr, lsa);
2038 DISCARD_LSA (lsa, 6);
2039 }
2040 }
2041
2042 /* The database copy is more recent. If the database copy
2043 has LS age equal to MaxAge and LS sequence number equal to
2044 MaxSequenceNumber, simply discard the received LSA without
2045 acknowledging it. (In this case, the LSA's LS sequence number is
2046 wrapping, and the MaxSequenceNumber LSA must be completely
2047 flushed before any new LSA instance can be introduced). */
2048
2049 else if (ret > 0) /* Database copy is more recent */
2050 {
2051 if (IS_LSA_MAXAGE (current) &&
2052 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
2053 {
2054 DISCARD_LSA (lsa, 7);
2055 }
2056 /* Otherwise, as long as the database copy has not been sent in a
2057 Link State Update within the last MinLSArrival seconds, send the
2058 database copy back to the sending neighbor, encapsulated within
2059 a Link State Update Packet. The Link State Update Packet should
2060 be sent directly to the neighbor. In so doing, do not put the
2061 database copy of the LSA on the neighbor's link state
2062 retransmission list, and do not acknowledge the received (less
2063 recent) LSA instance. */
2064 else
2065 {
2066 struct timeval now;
2067
Paul Jakma2518efd2006-08-27 06:49:29 +00002068 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00002069
2070 if (tv_cmp (tv_sub (now, current->tv_orig),
Paul Jakma2c9f8e32010-01-11 16:22:12 +00002071 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
paul718e3742002-12-13 20:15:29 +00002072 /* Trap NSSA type later.*/
2073 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2074 DISCARD_LSA (lsa, 8);
2075 }
2076 }
2077 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002078#undef DISCARD_LSA
2079
paul718e3742002-12-13 20:15:29 +00002080 assert (listcount (lsas) == 0);
2081 list_delete (lsas);
2082}
2083
2084/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002085static void
paul718e3742002-12-13 20:15:29 +00002086ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2087 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2088{
2089 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002090
paul718e3742002-12-13 20:15:29 +00002091 /* increment statistics. */
2092 oi->ls_ack_in++;
2093
pauld3f0d622004-05-05 15:27:15 +00002094 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002095 if (nbr == NULL)
2096 {
2097 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2098 inet_ntoa (ospfh->router_id));
2099 return;
2100 }
2101
Paul Jakma57c5c652010-01-07 06:12:53 +00002102 /* Add event to thread. */
2103 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2104
paul718e3742002-12-13 20:15:29 +00002105 if (nbr->state < NSM_Exchange)
2106 {
ajs3aa8d5f2004-12-11 18:00:06 +00002107 zlog_warn ("Link State Acknowledgment: "
2108 "Neighbor[%s] state %s is less than Exchange",
2109 inet_ntoa (ospfh->router_id),
2110 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002111 return;
2112 }
paul69310a62005-05-11 18:09:59 +00002113
paul718e3742002-12-13 20:15:29 +00002114 while (size >= OSPF_LSA_HEADER_SIZE)
2115 {
2116 struct ospf_lsa *lsa, *lsr;
2117
2118 lsa = ospf_lsa_new ();
2119 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2120
2121 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2122 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002123 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002124
2125 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2126 {
2127 lsa->data = NULL;
2128 ospf_lsa_discard (lsa);
2129 continue;
2130 }
2131
2132 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2133
Lu Feng49d7af12014-02-21 08:11:15 +00002134 if (lsr != NULL && ospf_lsa_more_recent (lsr, lsa) == 0)
paul718e3742002-12-13 20:15:29 +00002135 {
2136#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002137 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002138 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002139#endif /* HAVE_OPAQUE_LSA */
2140
2141 ospf_ls_retransmit_delete (nbr, lsr);
2142 }
2143
2144 lsa->data = NULL;
2145 ospf_lsa_discard (lsa);
2146 }
2147
paul718e3742002-12-13 20:15:29 +00002148 return;
paul718e3742002-12-13 20:15:29 +00002149}
David Lamparter6b0655a2014-06-04 06:53:35 +02002150
ajs038163f2005-02-17 19:55:59 +00002151static struct stream *
ajs5c333492005-02-23 15:43:01 +00002152ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002153{
2154 int ret;
ajs5c333492005-02-23 15:43:01 +00002155 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002156 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002157 unsigned int ifindex = 0;
2158 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002159 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002160 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002161 struct msghdr msgh;
2162
paul68defd62004-09-27 07:27:13 +00002163 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002164 msgh.msg_iov = &iov;
2165 msgh.msg_iovlen = 1;
2166 msgh.msg_control = (caddr_t) buff;
2167 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002168
ajs5c333492005-02-23 15:43:01 +00002169 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2170 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002171 {
ajs5c333492005-02-23 15:43:01 +00002172 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2173 return NULL;
2174 }
paul69310a62005-05-11 18:09:59 +00002175 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002176 {
2177 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2178 "(ip header size is %u)",
2179 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002180 return NULL;
2181 }
paul18b12c32004-10-05 14:38:29 +00002182
ajs5c333492005-02-23 15:43:01 +00002183 /* Note that there should not be alignment problems with this assignment
2184 because this is at the beginning of the stream data buffer. */
2185 iph = (struct ip *) STREAM_DATA(ibuf);
2186 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002187
ajs5c333492005-02-23 15:43:01 +00002188 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002189
Dmitrij Tejblumde5ccb92011-12-12 20:30:10 +04002190#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
paul718e3742002-12-13 20:15:29 +00002191 /*
2192 * Kernel network code touches incoming IP header parameters,
2193 * before protocol specific processing.
2194 *
2195 * 1) Convert byteorder to host representation.
2196 * --> ip_len, ip_id, ip_off
2197 *
2198 * 2) Adjust ip_len to strip IP header size!
2199 * --> If user process receives entire IP packet via RAW
2200 * socket, it must consider adding IP header size to
2201 * the "ip_len" field of "ip" structure.
2202 *
2203 * For more details, see <netinet/ip_input.c>.
2204 */
ajs5c333492005-02-23 15:43:01 +00002205 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002206#endif
2207
David BÉRARD0150c9c2010-05-11 10:17:53 +02002208#if defined(__DragonFly__)
2209 /*
2210 * in DragonFly's raw socket, ip_len/ip_off are read
2211 * in network byte order.
2212 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2213 */
2214 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2215#endif
2216
paul863082d2004-08-19 04:43:43 +00002217 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002218
2219 *ifp = if_lookup_by_index (ifindex);
2220
2221 if (ret != ip_len)
2222 {
ajs5c333492005-02-23 15:43:01 +00002223 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2224 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002225 return NULL;
2226 }
2227
2228 return ibuf;
2229}
2230
paul4dadc292005-05-06 21:37:42 +00002231static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002232ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002233 struct ip *iph, struct ospf_header *ospfh)
2234{
2235 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002236 struct ospf_vl_data *vl_data;
2237 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002238 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002239
2240 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2241 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002242 return NULL;
paul718e3742002-12-13 20:15:29 +00002243
pauld3f0d622004-05-05 15:27:15 +00002244 /* look for local OSPF interface matching the destination
2245 * to determine Area ID. We presume therefore the destination address
2246 * is unique, or at least (for "unnumbered" links), not used in other
2247 * areas
2248 */
2249 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2250 iph->ip_dst)) == NULL)
2251 return NULL;
paul718e3742002-12-13 20:15:29 +00002252
paul1eb8ef22005-04-07 07:30:20 +00002253 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002254 {
paul020709f2003-04-04 02:44:16 +00002255 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002256 if (!vl_area)
2257 continue;
2258
2259 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2260 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2261 {
2262 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002263 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002264 IF_NAME (vl_data->vl_oi));
2265 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2266 {
2267 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002268 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002269 return NULL;
2270 }
2271
2272 return vl_data->vl_oi;
2273 }
2274 }
2275
2276 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002277 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002278
pauld3f0d622004-05-05 15:27:15 +00002279 return NULL;
paul718e3742002-12-13 20:15:29 +00002280}
2281
Paul Jakmaf63f06d2011-04-08 12:44:43 +01002282static int
paul718e3742002-12-13 20:15:29 +00002283ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2284{
2285 /* Check match the Area ID of the receiving interface. */
2286 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2287 return 1;
2288
2289 return 0;
2290}
2291
2292/* Unbound socket will accept any Raw IP packets if proto is matched.
2293 To prevent it, compare src IP address and i/f address with masking
2294 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002295static int
paul718e3742002-12-13 20:15:29 +00002296ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2297{
2298 struct in_addr mask, me, him;
2299
2300 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2301 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2302 return 1;
2303
2304 masklen2ip (oi->address->prefixlen, &mask);
2305
2306 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2307 him.s_addr = ip_src.s_addr & mask.s_addr;
2308
2309 if (IPV4_ADDR_SAME (&me, &him))
2310 return 1;
2311
2312 return 0;
2313}
2314
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002315/* Return 1, if the packet is properly authenticated and checksummed,
2316 0 otherwise. In particular, check that AuType header field is valid and
2317 matches the locally configured AuType, and that D.5 requirements are met. */
paul4dadc292005-05-06 21:37:42 +00002318static int
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002319ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +00002320{
paul718e3742002-12-13 20:15:29 +00002321 struct crypt_key *ck;
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002322 u_int16_t iface_auth_type;
2323 u_int16_t pkt_auth_type = ntohs (ospfh->auth_type);
paul718e3742002-12-13 20:15:29 +00002324
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002325 switch (pkt_auth_type)
2326 {
2327 case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
2328 if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))
paul718e3742002-12-13 20:15:29 +00002329 {
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002330 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2331 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null",
2332 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2333 return 0;
paul718e3742002-12-13 20:15:29 +00002334 }
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002335 if (! ospf_check_sum (ospfh))
2336 {
2337 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2338 zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s",
2339 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2340 return 0;
2341 }
2342 return 1;
2343 case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */
2344 if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi)))
2345 {
2346 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2347 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple",
2348 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2349 return 0;
2350 }
2351 if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2352 {
2353 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2354 zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi));
2355 return 0;
2356 }
2357 if (! ospf_check_sum (ospfh))
2358 {
2359 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2360 zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s",
2361 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2362 return 0;
2363 }
2364 return 1;
2365 case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */
2366 if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi)))
2367 {
2368 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2369 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2370 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2371 return 0;
2372 }
2373 if (ospfh->checksum)
2374 {
2375 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2376 zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi));
2377 return 0;
2378 }
2379 /* only MD5 crypto method can pass ospf_packet_examin() */
2380 if
2381 (
2382 NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) ||
2383 ospfh->u.crypt.key_id != ck->key_id ||
2384 /* Condition above uses the last key ID on the list, which is
2385 different from what ospf_crypt_key_lookup() does. A bug? */
2386 ! ospf_check_md5_digest (oi, ospfh)
2387 )
2388 {
2389 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2390 zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi));
2391 return 0;
2392 }
2393 return 1;
2394 default:
2395 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2396 zlog_warn ("interface %s: invalid packet auth-type (%02x)",
2397 IF_NAME (oi), pkt_auth_type);
2398 return 0;
2399 }
paul718e3742002-12-13 20:15:29 +00002400}
2401
paul4dadc292005-05-06 21:37:42 +00002402static int
paul718e3742002-12-13 20:15:29 +00002403ospf_check_sum (struct ospf_header *ospfh)
2404{
2405 u_int32_t ret;
2406 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002407
2408 /* clear auth_data for checksum. */
2409 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2410
2411 /* keep checksum and clear. */
2412 sum = ospfh->checksum;
2413 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2414
2415 /* calculate checksum. */
2416 ret = in_cksum (ospfh, ntohs (ospfh->length));
2417
2418 if (ret != sum)
2419 {
2420 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2421 ret, sum);
2422 return 0;
2423 }
2424
2425 return 1;
2426}
2427
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002428/* Verify, that given link/TOS records are properly sized/aligned and match
2429 Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2430static unsigned
2431ospf_router_lsa_links_examin
2432(
2433 struct router_lsa_link * link,
2434 u_int16_t linkbytes,
2435 const u_int16_t num_links
2436)
2437{
2438 unsigned counted_links = 0, thislinklen;
2439
2440 while (linkbytes)
2441 {
2442 thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
2443 if (thislinklen > linkbytes)
2444 {
2445 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2446 zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
2447 return MSG_NG;
2448 }
2449 link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
2450 linkbytes -= thislinklen;
2451 counted_links++;
2452 }
2453 if (counted_links != num_links)
2454 {
2455 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2456 zlog_debug ("%s: %u link blocks declared, %u present",
2457 __func__, num_links, counted_links);
2458 return MSG_NG;
2459 }
2460 return MSG_OK;
2461}
2462
2463/* Verify, that the given LSA is properly sized/aligned (including type-specific
2464 minimum length constraint). */
2465static unsigned
2466ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
2467{
2468 unsigned ret;
2469 struct router_lsa * rlsa;
2470 if
2471 (
2472 lsah->type < OSPF_MAX_LSA &&
2473 ospf_lsa_minlen[lsah->type] &&
2474 lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
2475 )
2476 {
2477 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2478 zlog_debug ("%s: undersized (%u B) %s",
2479 __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
2480 return MSG_NG;
2481 }
2482 switch (lsah->type)
2483 {
2484 case OSPF_ROUTER_LSA:
2485 /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
2486 if (headeronly)
2487 {
2488 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2489 break;
2490 }
2491 rlsa = (struct router_lsa *) lsah;
2492 ret = ospf_router_lsa_links_examin
2493 (
2494 (struct router_lsa_link *) rlsa->link,
2495 lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
2496 ntohs (rlsa->links) /* 16 bits */
2497 );
2498 break;
2499 case OSPF_AS_EXTERNAL_LSA:
2500 /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
2501 case OSPF_AS_NSSA_LSA:
2502 /* RFC3101 C, idem */
2503 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
2504 break;
2505 /* Following LSA types are considered OK length-wise as soon as their minimum
2506 * length constraint is met and length of the whole LSA is a multiple of 4
2507 * (basic LSA header size is already a multiple of 4). */
2508 case OSPF_NETWORK_LSA:
2509 /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2510 case OSPF_SUMMARY_LSA:
2511 case OSPF_ASBR_SUMMARY_LSA:
2512 /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
2513#ifdef HAVE_OPAQUE_LSA
2514 case OSPF_OPAQUE_LINK_LSA:
2515 case OSPF_OPAQUE_AREA_LSA:
2516 case OSPF_OPAQUE_AS_LSA:
2517 /* RFC5250 A.2, "some number of octets (of application-specific
2518 * data) padded to 32-bit alignment." This is considered equivalent
2519 * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
2520 * file for the detailed analysis of this passage. */
2521#endif
2522 ret = lsalen % 4 ? MSG_NG : MSG_OK;
2523 break;
2524 default:
2525 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2526 zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
2527 return MSG_NG;
2528 }
2529 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2530 zlog_debug ("%s: alignment error in %s",
2531 __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
2532 return ret;
2533}
2534
2535/* Verify if the provided input buffer is a valid sequence of LSAs. This
2536 includes verification of LSA blocks length/alignment and dispatching
2537 of deeper-level checks. */
2538static unsigned
2539ospf_lsaseq_examin
2540(
2541 struct lsa_header *lsah, /* start of buffered data */
2542 size_t length,
2543 const u_char headeronly,
2544 /* When declared_num_lsas is not 0, compare it to the real number of LSAs
2545 and treat the difference as an error. */
2546 const u_int32_t declared_num_lsas
2547)
2548{
2549 u_int32_t counted_lsas = 0;
2550
2551 while (length)
2552 {
2553 u_int16_t lsalen;
2554 if (length < OSPF_LSA_HEADER_SIZE)
2555 {
2556 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2557 zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
2558 __func__, length, counted_lsas);
2559 return MSG_NG;
2560 }
2561 /* save on ntohs() calls here and in the LSA validator */
2562 lsalen = ntohs (lsah->length);
2563 if (lsalen < OSPF_LSA_HEADER_SIZE)
2564 {
2565 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2566 zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
2567 __func__, counted_lsas, lsalen);
2568 return MSG_NG;
2569 }
2570 if (headeronly)
2571 {
2572 /* less checks here and in ospf_lsa_examin() */
2573 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
2574 {
2575 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2576 zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
2577 return MSG_NG;
2578 }
2579 lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
2580 length -= OSPF_LSA_HEADER_SIZE;
2581 }
2582 else
2583 {
2584 /* make sure the input buffer is deep enough before further checks */
2585 if (lsalen > length)
2586 {
2587 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2588 zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2589 __func__, counted_lsas, lsalen, length);
2590 return MSG_NG;
2591 }
2592 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
2593 {
2594 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2595 zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
2596 return MSG_NG;
2597 }
2598 lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
2599 length -= lsalen;
2600 }
2601 counted_lsas++;
2602 }
2603
2604 if (declared_num_lsas && counted_lsas != declared_num_lsas)
2605 {
2606 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2607 zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
2608 __func__, declared_num_lsas, counted_lsas);
2609 return MSG_NG;
2610 }
2611 return MSG_OK;
2612}
2613
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002614/* Verify a complete OSPF packet for proper sizing/alignment. */
2615static unsigned
2616ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2617{
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002618 u_int16_t bytesdeclared, bytesauth;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002619 unsigned ret;
2620 struct ospf_ls_update * lsupd;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002621
2622 /* Length, 1st approximation. */
2623 if (bytesonwire < OSPF_HEADER_SIZE)
2624 {
2625 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2626 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2627 return MSG_NG;
2628 }
2629 /* Now it is safe to access header fields. Performing length check, allow
2630 * for possible extra bytes of crypto auth/padding, which are not counted
2631 * in the OSPF header "length" field. */
Denis Ovsienkoaee56742012-02-28 15:15:29 +04002632 if (oh->version != OSPF_VERSION)
2633 {
2634 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2635 zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
2636 return MSG_NG;
2637 }
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002638 bytesdeclared = ntohs (oh->length);
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002639 if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2640 bytesauth = 0;
2641 else
2642 {
2643 if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE)
2644 {
2645 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2646 zlog_debug ("%s: unsupported crypto auth length (%u B)",
2647 __func__, oh->u.crypt.auth_data_len);
2648 return MSG_NG;
2649 }
2650 bytesauth = OSPF_AUTH_MD5_SIZE;
2651 }
2652 if (bytesdeclared + bytesauth > bytesonwire)
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002653 {
2654 if (IS_DEBUG_OSPF_PACKET (0, RECV))
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002655 zlog_debug ("%s: packet length error (%u real, %u+%u declared)",
2656 __func__, bytesonwire, bytesdeclared, bytesauth);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002657 return MSG_NG;
2658 }
2659 /* Length, 2nd approximation. The type-specific constraint is checked
2660 against declared length, not amount of bytes on wire. */
2661 if
2662 (
2663 oh->type >= OSPF_MSG_HELLO &&
2664 oh->type <= OSPF_MSG_LS_ACK &&
2665 bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2666 )
2667 {
2668 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2669 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2670 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2671 return MSG_NG;
2672 }
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002673 switch (oh->type)
2674 {
2675 case OSPF_MSG_HELLO:
2676 /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
2677 by N>=0 router-IDs. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002678 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002679 break;
2680 case OSPF_MSG_DB_DESC:
2681 /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
2682 by N>=0 header-only LSAs. */
2683 ret = ospf_lsaseq_examin
2684 (
2685 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002686 bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002687 1, /* header-only LSAs */
2688 0
2689 );
2690 break;
2691 case OSPF_MSG_LS_REQ:
2692 /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002693 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002694 OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
2695 break;
2696 case OSPF_MSG_LS_UPD:
2697 /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
2698 by N>=0 full LSAs (with N declared beforehand). */
2699 lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
2700 ret = ospf_lsaseq_examin
2701 (
2702 (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002703 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002704 0, /* full LSAs */
2705 ntohl (lsupd->num_lsas) /* 32 bits */
2706 );
2707 break;
2708 case OSPF_MSG_LS_ACK:
2709 /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
2710 ret = ospf_lsaseq_examin
2711 (
2712 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002713 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002714 1, /* header-only LSAs */
2715 0
2716 );
2717 break;
2718 default:
2719 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2720 zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
2721 return MSG_NG;
2722 }
2723 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2724 zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
2725 return ret;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002726}
2727
paul718e3742002-12-13 20:15:29 +00002728/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002729static int
paul718e3742002-12-13 20:15:29 +00002730ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2731 struct ip *iph, struct ospf_header *ospfh)
2732{
paul718e3742002-12-13 20:15:29 +00002733 /* Check Area ID. */
2734 if (!ospf_check_area_id (oi, ospfh))
2735 {
2736 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2737 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2738 return -1;
2739 }
2740
2741 /* Check network mask, Silently discarded. */
2742 if (! ospf_check_network_mask (oi, iph->ip_src))
2743 {
2744 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2745 IF_NAME (oi), inet_ntoa (iph->ip_src));
2746 return -1;
2747 }
2748
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002749 /* Check authentication. The function handles logging actions, where required. */
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002750 if (! ospf_check_auth (oi, ospfh))
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002751 return -1;
paul718e3742002-12-13 20:15:29 +00002752
2753 return 0;
2754}
2755
2756/* Starting point of packet process function. */
2757int
2758ospf_read (struct thread *thread)
2759{
2760 int ret;
2761 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002762 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002763 struct ospf_interface *oi;
2764 struct ip *iph;
2765 struct ospf_header *ospfh;
2766 u_int16_t length;
2767 struct interface *ifp;
2768
2769 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002770 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002771
2772 /* prepare for next packet. */
2773 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002774
ajs5c333492005-02-23 15:43:01 +00002775 stream_reset(ospf->ibuf);
2776 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002777 return -1;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002778 /* This raw packet is known to be at least as big as its IP header. */
paul718e3742002-12-13 20:15:29 +00002779
ajs5c333492005-02-23 15:43:01 +00002780 /* Note that there should not be alignment problems with this assignment
2781 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002782 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002783 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002784
paulac191232004-10-22 12:05:17 +00002785 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002786 /* Handle cases where the platform does not support retrieving the ifindex,
2787 and also platforms (such as Solaris 8) that claim to support ifindex
2788 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002789 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002790
pauld3f0d622004-05-05 15:27:15 +00002791 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002792 return 0;
paul718e3742002-12-13 20:15:29 +00002793
2794 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002795 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002796 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002797
paul718e3742002-12-13 20:15:29 +00002798 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002799 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002800 {
pauld3241812003-09-29 12:42:39 +00002801 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2802 {
ajs2a42e282004-12-08 18:43:03 +00002803 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002804 inet_ntoa (iph->ip_src));
2805 }
paul718e3742002-12-13 20:15:29 +00002806 return 0;
2807 }
2808
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002809 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2810 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002811 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002812
paul718e3742002-12-13 20:15:29 +00002813 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002814 if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
2815 return -1;
2816 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002817
2818 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002819 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002820
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002821 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2822 after the passive/backbone/other checks below are passed. These checks
2823 in turn access the fields of unverified "ospfh" structure for their own
2824 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002825
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002826 /* If incoming interface is passive one, ignore it. */
2827 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2828 {
2829 char buf[3][INET_ADDRSTRLEN];
2830
2831 if (IS_DEBUG_OSPF_EVENT)
2832 zlog_debug ("ignoring packet from router %s sent to %s, "
2833 "received on a passive interface, %s",
2834 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2835 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2836 inet_ntop(AF_INET, &oi->address->u.prefix4,
2837 buf[2], sizeof(buf[2])));
2838
2839 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2840 {
2841 /* Try to fix multicast membership.
2842 * Some OS:es may have problems in this area,
2843 * make sure it is removed.
2844 */
2845 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2846 ospf_if_set_multicast(oi);
2847 }
2848 return 0;
2849 }
2850
2851
pauld3f0d622004-05-05 15:27:15 +00002852 /* if no local ospf_interface,
2853 * or header area is backbone but ospf_interface is not
2854 * check for VLINK interface
2855 */
2856 if ( (oi == NULL) ||
2857 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2858 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2859 )
2860 {
2861 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2862 {
Paul Jakma88871b12006-06-15 11:41:19 +00002863 if (IS_DEBUG_OSPF_EVENT)
2864 zlog_debug ("Packet from [%s] received on link %s"
2865 " but no ospf_interface",
2866 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002867 return 0;
2868 }
2869 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002870
pauld3f0d622004-05-05 15:27:15 +00002871 /* else it must be a local ospf interface, check it was received on
2872 * correct link
2873 */
2874 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002875 {
Paul Jakma11637432009-08-11 12:25:42 +01002876 if (IS_DEBUG_OSPF_EVENT)
2877 zlog_warn ("Packet from [%s] received on wrong link %s",
2878 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002879 return 0;
2880 }
ajs847947f2005-02-02 18:38:48 +00002881 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002882 {
ajsba6454e2005-02-08 15:37:30 +00002883 char buf[2][INET_ADDRSTRLEN];
2884 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002885 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002886 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2887 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2888 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002889 /* Fix multicast memberships? */
2890 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002891 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002892 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002893 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002894 if (oi->multicast_memberships)
2895 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002896 return 0;
2897 }
paul718e3742002-12-13 20:15:29 +00002898
2899 /*
2900 * If the received packet is destined for AllDRouters, the packet
2901 * should be accepted only if the received ospf interface state is
2902 * either DR or Backup -- endo.
2903 */
2904 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2905 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2906 {
ajsba6454e2005-02-08 15:37:30 +00002907 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002908 inet_ntoa (iph->ip_src), IF_NAME (oi),
2909 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002910 /* Try to fix multicast membership. */
2911 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2912 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002913 return 0;
2914 }
2915
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002916 /* Verify more OSPF header fields. */
2917 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2918 if (ret < 0)
2919 {
2920 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2921 zlog_debug ("ospf_read[%s]: Header check failed, "
2922 "dropping.",
2923 inet_ntoa (iph->ip_src));
2924 return ret;
2925 }
2926
paul718e3742002-12-13 20:15:29 +00002927 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002928 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2929 {
paul718e3742002-12-13 20:15:29 +00002930 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002931 {
ajs2a42e282004-12-08 18:43:03 +00002932 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002933 ospf_packet_dump (ibuf);
2934 }
paul718e3742002-12-13 20:15:29 +00002935
ajs2a42e282004-12-08 18:43:03 +00002936 zlog_debug ("%s received from [%s] via [%s]",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +04002937 LOOKUP (ospf_packet_type_str, ospfh->type),
paul1aa7b392003-04-08 08:51:58 +00002938 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002939 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2940 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002941
2942 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002943 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002944 }
paul718e3742002-12-13 20:15:29 +00002945
paul9985f832005-02-09 15:51:56 +00002946 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002947
2948 /* Adjust size to message length. */
2949 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2950
2951 /* Read rest of the packet and call each sort of packet routine. */
2952 switch (ospfh->type)
2953 {
2954 case OSPF_MSG_HELLO:
2955 ospf_hello (iph, ospfh, ibuf, oi, length);
2956 break;
2957 case OSPF_MSG_DB_DESC:
2958 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2959 break;
2960 case OSPF_MSG_LS_REQ:
2961 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2962 break;
2963 case OSPF_MSG_LS_UPD:
2964 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2965 break;
2966 case OSPF_MSG_LS_ACK:
2967 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2968 break;
2969 default:
2970 zlog (NULL, LOG_WARNING,
2971 "interface %s: OSPF packet header type %d is illegal",
2972 IF_NAME (oi), ospfh->type);
2973 break;
2974 }
2975
paul718e3742002-12-13 20:15:29 +00002976 return 0;
2977}
2978
2979/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002980static void
paul718e3742002-12-13 20:15:29 +00002981ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2982{
2983 struct ospf_header *ospfh;
2984
2985 ospfh = (struct ospf_header *) STREAM_DATA (s);
2986
2987 ospfh->version = (u_char) OSPF_VERSION;
2988 ospfh->type = (u_char) type;
2989
paul68980082003-03-25 05:07:42 +00002990 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002991
2992 ospfh->checksum = 0;
2993 ospfh->area_id = oi->area->area_id;
2994 ospfh->auth_type = htons (ospf_auth_type (oi));
2995
2996 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2997
paul9985f832005-02-09 15:51:56 +00002998 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002999}
3000
3001/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00003002static int
paul718e3742002-12-13 20:15:29 +00003003ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
3004{
3005 struct crypt_key *ck;
3006
3007 switch (ospf_auth_type (oi))
3008 {
3009 case OSPF_AUTH_NULL:
3010 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
3011 break;
3012 case OSPF_AUTH_SIMPLE:
3013 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
3014 OSPF_AUTH_SIMPLE_SIZE);
3015 break;
3016 case OSPF_AUTH_CRYPTOGRAPHIC:
3017 /* If key is not set, then set 0. */
3018 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
3019 {
3020 ospfh->u.crypt.zero = 0;
3021 ospfh->u.crypt.key_id = 0;
3022 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
3023 }
3024 else
3025 {
paul1eb8ef22005-04-07 07:30:20 +00003026 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00003027 ospfh->u.crypt.zero = 0;
3028 ospfh->u.crypt.key_id = ck->key_id;
3029 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
3030 }
3031 /* note: the seq is done in ospf_make_md5_digest() */
3032 break;
3033 default:
3034 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
3035 break;
3036 }
3037
3038 return 0;
3039}
3040
3041/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00003042static void
paul718e3742002-12-13 20:15:29 +00003043ospf_fill_header (struct ospf_interface *oi,
3044 struct stream *s, u_int16_t length)
3045{
3046 struct ospf_header *ospfh;
3047
3048 ospfh = (struct ospf_header *) STREAM_DATA (s);
3049
3050 /* Fill length. */
3051 ospfh->length = htons (length);
3052
3053 /* Calculate checksum. */
3054 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
3055 ospfh->checksum = in_cksum (ospfh, length);
3056 else
3057 ospfh->checksum = 0;
3058
3059 /* Add Authentication Data. */
3060 ospf_make_auth (oi, ospfh);
3061}
3062
paul4dadc292005-05-06 21:37:42 +00003063static int
paul718e3742002-12-13 20:15:29 +00003064ospf_make_hello (struct ospf_interface *oi, struct stream *s)
3065{
3066 struct ospf_neighbor *nbr;
3067 struct route_node *rn;
3068 u_int16_t length = OSPF_HELLO_MIN_SIZE;
3069 struct in_addr mask;
3070 unsigned long p;
3071 int flag = 0;
3072
3073 /* Set netmask of interface. */
3074 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
3075 oi->type != OSPF_IFTYPE_VIRTUALLINK)
3076 masklen2ip (oi->address->prefixlen, &mask);
3077 else
3078 memset ((char *) &mask, 0, sizeof (struct in_addr));
3079 stream_put_ipv4 (s, mask.s_addr);
3080
3081 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00003082 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
3083 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
3084 else
3085 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00003086
3087 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003088 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00003089 OPTIONS(oi), IF_NAME (oi));
3090
3091 /* Set Options. */
3092 stream_putc (s, OPTIONS (oi));
3093
3094 /* Set Router Priority. */
3095 stream_putc (s, PRIORITY (oi));
3096
3097 /* Set Router Dead Interval. */
3098 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
3099
3100 /* Set Designated Router. */
3101 stream_put_ipv4 (s, DR (oi).s_addr);
3102
paul9985f832005-02-09 15:51:56 +00003103 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003104
3105 /* Set Backup Designated Router. */
3106 stream_put_ipv4 (s, BDR (oi).s_addr);
3107
3108 /* Add neighbor seen. */
3109 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00003110 if ((nbr = rn->info))
3111 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
3112 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
3113 if (nbr->state != NSM_Down) /* This is myself for DR election. */
3114 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003115 {
3116 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00003117 if (nbr->d_router.s_addr != 0
3118 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
3119 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
3120 flag = 1;
paul718e3742002-12-13 20:15:29 +00003121
3122 stream_put_ipv4 (s, nbr->router_id.s_addr);
3123 length += 4;
3124 }
3125
3126 /* Let neighbor generate BackupSeen. */
3127 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00003128 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00003129
3130 return length;
3131}
3132
paul4dadc292005-05-06 21:37:42 +00003133static int
paul718e3742002-12-13 20:15:29 +00003134ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
3135 struct stream *s)
3136{
3137 struct ospf_lsa *lsa;
3138 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
3139 u_char options;
3140 unsigned long pp;
3141 int i;
3142 struct ospf_lsdb *lsdb;
3143
3144 /* Set Interface MTU. */
3145 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3146 stream_putw (s, 0);
3147 else
3148 stream_putw (s, oi->ifp->mtu);
3149
3150 /* Set Options. */
3151 options = OPTIONS (oi);
3152#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003153 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00003154 {
3155 if (IS_SET_DD_I (nbr->dd_flags)
3156 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
3157 /*
3158 * Set O-bit in the outgoing DD packet for capablity negotiation,
3159 * if one of following case is applicable.
3160 *
3161 * 1) WaitTimer expiration event triggered the neighbor state to
3162 * change to Exstart, but no (valid) DD packet has received
3163 * from the neighbor yet.
3164 *
3165 * 2) At least one DD packet with O-bit on has received from the
3166 * neighbor.
3167 */
3168 SET_FLAG (options, OSPF_OPTION_O);
3169 }
3170#endif /* HAVE_OPAQUE_LSA */
3171 stream_putc (s, options);
3172
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003173 /* DD flags */
paul9985f832005-02-09 15:51:56 +00003174 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003175 stream_putc (s, nbr->dd_flags);
3176
3177 /* Set DD Sequence Number. */
3178 stream_putl (s, nbr->dd_seqnum);
3179
Paul Jakmab5aeb442006-08-30 18:47:37 +00003180 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00003181 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00003182 goto empty;
paul718e3742002-12-13 20:15:29 +00003183
3184 /* Describe LSA Header from Database Summary List. */
3185 lsdb = &nbr->db_sum;
3186
3187 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3188 {
3189 struct route_table *table = lsdb->type[i].db;
3190 struct route_node *rn;
3191
3192 for (rn = route_top (table); rn; rn = route_next (rn))
3193 if ((lsa = rn->info) != NULL)
3194 {
3195#ifdef HAVE_OPAQUE_LSA
3196 if (IS_OPAQUE_LSA (lsa->data->type)
3197 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
3198 {
3199 /* Suppress advertising opaque-informations. */
3200 /* Remove LSA from DB summary list. */
3201 ospf_lsdb_delete (lsdb, lsa);
3202 continue;
3203 }
3204#endif /* HAVE_OPAQUE_LSA */
3205
3206 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
3207 {
3208 struct lsa_header *lsah;
3209 u_int16_t ls_age;
3210
3211 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003212 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003213 break;
3214
3215 /* Keep pointer to LS age. */
3216 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00003217 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003218
3219 /* Proceed stream pointer. */
3220 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3221 length += OSPF_LSA_HEADER_SIZE;
3222
3223 /* Set LS age. */
3224 ls_age = LS_AGE (lsa);
3225 lsah->ls_age = htons (ls_age);
3226
3227 }
3228
3229 /* Remove LSA from DB summary list. */
3230 ospf_lsdb_delete (lsdb, lsa);
3231 }
3232 }
3233
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003234 /* Update 'More' bit */
3235 if (ospf_db_summary_isempty (nbr))
3236 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00003237empty:
3238 if (nbr->state >= NSM_Exchange)
3239 {
3240 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
3241 /* Rewrite DD flags */
3242 stream_putc_at (s, pp, nbr->dd_flags);
3243 }
3244 else
3245 {
3246 assert (IS_SET_DD_M(nbr->dd_flags));
3247 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003248 }
paul718e3742002-12-13 20:15:29 +00003249 return length;
3250}
3251
paul4dadc292005-05-06 21:37:42 +00003252static int
paul718e3742002-12-13 20:15:29 +00003253ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
3254 unsigned long delta, struct ospf_neighbor *nbr,
3255 struct ospf_lsa *lsa)
3256{
3257 struct ospf_interface *oi;
3258
3259 oi = nbr->oi;
3260
3261 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003262 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00003263 return 0;
3264
3265 stream_putl (s, lsa->data->type);
3266 stream_put_ipv4 (s, lsa->data->id.s_addr);
3267 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
3268
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003269 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00003270 nbr->ls_req_last = ospf_lsa_lock (lsa);
3271
3272 *length += 12;
3273 return 1;
3274}
3275
paul4dadc292005-05-06 21:37:42 +00003276static int
paul718e3742002-12-13 20:15:29 +00003277ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
3278{
3279 struct ospf_lsa *lsa;
3280 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003281 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00003282 struct route_table *table;
3283 struct route_node *rn;
3284 int i;
3285 struct ospf_lsdb *lsdb;
3286
3287 lsdb = &nbr->ls_req;
3288
3289 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3290 {
3291 table = lsdb->type[i].db;
3292 for (rn = route_top (table); rn; rn = route_next (rn))
3293 if ((lsa = (rn->info)) != NULL)
3294 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
3295 {
3296 route_unlock_node (rn);
3297 break;
3298 }
3299 }
3300 return length;
3301}
3302
paul4dadc292005-05-06 21:37:42 +00003303static int
paul718e3742002-12-13 20:15:29 +00003304ls_age_increment (struct ospf_lsa *lsa, int delay)
3305{
3306 int age;
3307
3308 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
3309
3310 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3311}
3312
paul4dadc292005-05-06 21:37:42 +00003313static int
hasso52dc7ee2004-09-23 19:18:23 +00003314ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003315{
3316 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00003317 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003318 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00003319 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00003320 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003321 unsigned long pp;
3322 int count = 0;
3323
3324 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003325 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00003326
paul9985f832005-02-09 15:51:56 +00003327 pp = stream_get_endp (s);
3328 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003329 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00003330
gdt86f1fd92005-01-10 14:20:43 +00003331 /* Calculate amount of packet usable for data. */
3332 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3333
paul718e3742002-12-13 20:15:29 +00003334 while ((node = listhead (update)) != NULL)
3335 {
3336 struct lsa_header *lsah;
3337 u_int16_t ls_age;
3338
3339 if (IS_DEBUG_OSPF_EVENT)
Dinesh G Dutt1c063342014-09-30 13:04:45 -07003340 zlog_debug ("ospf_make_ls_upd: List Iteration %d", count);
paul718e3742002-12-13 20:15:29 +00003341
paul1eb8ef22005-04-07 07:30:20 +00003342 lsa = listgetdata (node);
3343
paul718e3742002-12-13 20:15:29 +00003344 assert (lsa->data);
3345
paul68b73392004-09-12 14:21:37 +00003346 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00003347 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00003348 break;
3349
paul718e3742002-12-13 20:15:29 +00003350 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00003351 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003352
3353 /* Put LSA to Link State Request. */
3354 stream_put (s, lsa->data, ntohs (lsa->data->length));
3355
3356 /* Set LS age. */
3357 /* each hop must increment an lsa_age by transmit_delay
3358 of OSPF interface */
3359 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3360 lsah->ls_age = htons (ls_age);
3361
3362 length += ntohs (lsa->data->length);
3363 count++;
3364
3365 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003366 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003367 }
3368
3369 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003370 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003371
3372 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003373 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003374 return length;
3375}
3376
paul4dadc292005-05-06 21:37:42 +00003377static int
hasso52dc7ee2004-09-23 19:18:23 +00003378ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003379{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003380 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003381 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003382 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003383 struct ospf_lsa *lsa;
3384
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003385 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003386 {
paul718e3742002-12-13 20:15:29 +00003387 assert (lsa);
3388
gdt86f1fd92005-01-10 14:20:43 +00003389 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003390 break;
3391
3392 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3393 length += OSPF_LSA_HEADER_SIZE;
3394
paul718e3742002-12-13 20:15:29 +00003395 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003396 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003397 }
3398
paul718e3742002-12-13 20:15:29 +00003399 return length;
3400}
3401
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003402static void
3403ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003404{
3405 struct ospf_packet *op;
3406 u_int16_t length = OSPF_HEADER_SIZE;
3407
3408 op = ospf_packet_new (oi->ifp->mtu);
3409
3410 /* Prepare OSPF common header. */
3411 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3412
3413 /* Prepare OSPF Hello body. */
3414 length += ospf_make_hello (oi, op->s);
3415
3416 /* Fill OSPF header. */
3417 ospf_fill_header (oi, op->s, length);
3418
3419 /* Set packet length. */
3420 op->length = length;
3421
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003422 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003423
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003424 /* Add packet to the top of the interface output queue, so that they
3425 * can't get delayed by things like long queues of LS Update packets
3426 */
3427 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003428
3429 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003430 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003431}
3432
paul4dadc292005-05-06 21:37:42 +00003433static void
paul718e3742002-12-13 20:15:29 +00003434ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3435{
3436 struct ospf_interface *oi;
3437
3438 oi = nbr_nbma->oi;
3439 assert(oi);
3440
3441 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003442 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003443 return;
3444
3445 if (oi->type != OSPF_IFTYPE_NBMA)
3446 return;
3447
3448 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3449 return;
3450
3451 if (PRIORITY(oi) == 0)
3452 return;
3453
3454 if (nbr_nbma->priority == 0
3455 && oi->state != ISM_DR && oi->state != ISM_Backup)
3456 return;
3457
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003458 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003459}
3460
3461int
3462ospf_poll_timer (struct thread *thread)
3463{
3464 struct ospf_nbr_nbma *nbr_nbma;
3465
3466 nbr_nbma = THREAD_ARG (thread);
3467 nbr_nbma->t_poll = NULL;
3468
3469 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003470 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003471 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3472
3473 ospf_poll_send (nbr_nbma);
3474
3475 if (nbr_nbma->v_poll > 0)
3476 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3477 nbr_nbma->v_poll);
3478
3479 return 0;
3480}
3481
3482
3483int
3484ospf_hello_reply_timer (struct thread *thread)
3485{
3486 struct ospf_neighbor *nbr;
3487
3488 nbr = THREAD_ARG (thread);
3489 nbr->t_hello_reply = NULL;
3490
3491 assert (nbr->oi);
3492
3493 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003494 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003495 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3496
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003497 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003498
3499 return 0;
3500}
3501
3502/* Send OSPF Hello. */
3503void
3504ospf_hello_send (struct ospf_interface *oi)
3505{
paul718e3742002-12-13 20:15:29 +00003506 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003507 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003508 return;
3509
paul718e3742002-12-13 20:15:29 +00003510 if (oi->type == OSPF_IFTYPE_NBMA)
3511 {
3512 struct ospf_neighbor *nbr;
3513 struct route_node *rn;
3514
3515 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3516 if ((nbr = rn->info))
3517 if (nbr != oi->nbr_self)
3518 if (nbr->state != NSM_Down)
3519 {
3520 /* RFC 2328 Section 9.5.1
3521 If the router is not eligible to become Designated Router,
3522 it must periodically send Hello Packets to both the
3523 Designated Router and the Backup Designated Router (if they
3524 exist). */
3525 if (PRIORITY(oi) == 0 &&
3526 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3527 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3528 continue;
3529
3530 /* If the router is eligible to become Designated Router, it
3531 must periodically send Hello Packets to all neighbors that
3532 are also eligible. In addition, if the router is itself the
3533 Designated Router or Backup Designated Router, it must also
3534 send periodic Hello Packets to all other neighbors. */
3535
3536 if (nbr->priority == 0 && oi->state == ISM_DROther)
3537 continue;
3538 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003539 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003540 }
paul718e3742002-12-13 20:15:29 +00003541 }
3542 else
3543 {
3544 /* Decide destination address. */
3545 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003546 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3547 else
3548 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003549 }
3550}
3551
3552/* Send OSPF Database Description. */
3553void
3554ospf_db_desc_send (struct ospf_neighbor *nbr)
3555{
3556 struct ospf_interface *oi;
3557 struct ospf_packet *op;
3558 u_int16_t length = OSPF_HEADER_SIZE;
3559
3560 oi = nbr->oi;
3561 op = ospf_packet_new (oi->ifp->mtu);
3562
3563 /* Prepare OSPF common header. */
3564 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3565
3566 /* Prepare OSPF Database Description body. */
3567 length += ospf_make_db_desc (oi, nbr, op->s);
3568
3569 /* Fill OSPF header. */
3570 ospf_fill_header (oi, op->s, length);
3571
3572 /* Set packet length. */
3573 op->length = length;
3574
3575 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003576 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3577 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3578 else
3579 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003580
3581 /* Add packet to the interface output queue. */
3582 ospf_packet_add (oi, op);
3583
3584 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003585 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003586
3587 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3588 if (nbr->last_send)
3589 ospf_packet_free (nbr->last_send);
3590 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003591 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003592}
3593
3594/* Re-send Database Description. */
3595void
3596ospf_db_desc_resend (struct ospf_neighbor *nbr)
3597{
3598 struct ospf_interface *oi;
3599
3600 oi = nbr->oi;
3601
3602 /* Add packet to the interface output queue. */
3603 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3604
3605 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003606 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003607}
3608
3609/* Send Link State Request. */
3610void
3611ospf_ls_req_send (struct ospf_neighbor *nbr)
3612{
3613 struct ospf_interface *oi;
3614 struct ospf_packet *op;
3615 u_int16_t length = OSPF_HEADER_SIZE;
3616
3617 oi = nbr->oi;
3618 op = ospf_packet_new (oi->ifp->mtu);
3619
3620 /* Prepare OSPF common header. */
3621 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3622
3623 /* Prepare OSPF Link State Request body. */
3624 length += ospf_make_ls_req (nbr, op->s);
3625 if (length == OSPF_HEADER_SIZE)
3626 {
3627 ospf_packet_free (op);
3628 return;
3629 }
3630
3631 /* Fill OSPF header. */
3632 ospf_fill_header (oi, op->s, length);
3633
3634 /* Set packet length. */
3635 op->length = length;
3636
3637 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003638 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3639 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3640 else
3641 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003642
3643 /* Add packet to the interface output queue. */
3644 ospf_packet_add (oi, op);
3645
3646 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003647 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003648
3649 /* Add Link State Request Retransmission Timer. */
3650 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3651}
3652
3653/* Send Link State Update with an LSA. */
3654void
3655ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3656 int flag)
3657{
hasso52dc7ee2004-09-23 19:18:23 +00003658 struct list *update;
paul718e3742002-12-13 20:15:29 +00003659
3660 update = list_new ();
3661
3662 listnode_add (update, lsa);
3663 ospf_ls_upd_send (nbr, update, flag);
3664
3665 list_delete (update);
3666}
3667
paul68b73392004-09-12 14:21:37 +00003668/* Determine size for packet. Must be at least big enough to accomodate next
3669 * LSA on list, which may be bigger than MTU size.
3670 *
3671 * Return pointer to new ospf_packet
3672 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3673 * on packet sizes (in which case offending LSA is deleted from update list)
3674 */
3675static struct ospf_packet *
3676ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3677{
3678 struct ospf_lsa *lsa;
3679 struct listnode *ln;
3680 size_t size;
3681 static char warned = 0;
3682
paul1eb8ef22005-04-07 07:30:20 +00003683 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003684 assert (lsa->data);
3685
3686 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3687 > ospf_packet_max (oi))
3688 {
3689 if (!warned)
3690 {
3691 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3692 "will need to fragment. Not optimal. Try divide up"
3693 " your network with areas. Use 'debug ospf packet send'"
3694 " to see details, or look at 'show ip ospf database ..'");
3695 warned = 1;
3696 }
3697
3698 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003699 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003700 " %d bytes originated by %s, will be fragmented!",
3701 inet_ntoa (lsa->data->id),
3702 ntohs (lsa->data->length),
3703 inet_ntoa (lsa->data->adv_router));
3704
3705 /*
3706 * Allocate just enough to fit this LSA only, to avoid including other
3707 * LSAs in fragmented LSA Updates.
3708 */
3709 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3710 + OSPF_LS_UPD_MIN_SIZE;
3711 }
3712 else
3713 size = oi->ifp->mtu;
3714
3715 if (size > OSPF_MAX_PACKET_SIZE)
3716 {
3717 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003718 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003719 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003720 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003721 (long int) size);
paul68b73392004-09-12 14:21:37 +00003722 list_delete_node (update, ln);
3723 return NULL;
3724 }
3725
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003726 /* IP header is built up separately by ospf_write(). This means, that we must
3727 * reduce the "affordable" size just calculated by length of an IP header.
3728 * This makes sure, that even if we manage to fill the payload with LSA data
3729 * completely, the final packet (our data plus IP header) still fits into
3730 * outgoing interface MTU. This correction isn't really meaningful for an
3731 * oversized LSA, but for consistency the correction is done for both cases.
3732 *
3733 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3734 */
3735 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003736}
3737
paul718e3742002-12-13 20:15:29 +00003738static void
hasso52dc7ee2004-09-23 19:18:23 +00003739ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003740 struct in_addr addr)
3741{
3742 struct ospf_packet *op;
3743 u_int16_t length = OSPF_HEADER_SIZE;
3744
3745 if (IS_DEBUG_OSPF_EVENT)
Dinesh G Dutt1c063342014-09-30 13:04:45 -07003746 zlog_debug ("listcount = %d, [%s]dst %s", listcount (update), IF_NAME(oi),
3747 inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003748
3749 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003750
3751 /* Prepare OSPF common header. */
3752 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3753
paul59ea14c2004-07-14 20:50:36 +00003754 /* Prepare OSPF Link State Update body.
3755 * Includes Type-7 translation.
3756 */
paul718e3742002-12-13 20:15:29 +00003757 length += ospf_make_ls_upd (oi, update, op->s);
3758
3759 /* Fill OSPF header. */
3760 ospf_fill_header (oi, op->s, length);
3761
3762 /* Set packet length. */
3763 op->length = length;
3764
3765 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003766 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3767 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3768 else
3769 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003770
3771 /* Add packet to the interface output queue. */
3772 ospf_packet_add (oi, op);
3773
3774 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003775 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003776}
3777
3778static int
3779ospf_ls_upd_send_queue_event (struct thread *thread)
3780{
3781 struct ospf_interface *oi = THREAD_ARG(thread);
3782 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003783 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003784 struct list *update;
paul68b73392004-09-12 14:21:37 +00003785 char again = 0;
paul718e3742002-12-13 20:15:29 +00003786
3787 oi->t_ls_upd_event = NULL;
3788
3789 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003790 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003791
paul736d3442003-07-24 23:22:57 +00003792 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003793 {
paul736d3442003-07-24 23:22:57 +00003794 rnext = route_next (rn);
3795
paul718e3742002-12-13 20:15:29 +00003796 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003797 continue;
paul68b73392004-09-12 14:21:37 +00003798
3799 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003800
paul48fe13b2004-07-27 17:40:44 +00003801 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003802
paul68b73392004-09-12 14:21:37 +00003803 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003804 if (listcount(update) == 0)
3805 {
3806 list_delete (rn->info);
3807 rn->info = NULL;
3808 route_unlock_node (rn);
3809 }
3810 else
paul68b73392004-09-12 14:21:37 +00003811 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003812 }
3813
3814 if (again != 0)
3815 {
3816 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003817 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003818 " %d nodes to try again, raising new event", again);
3819 oi->t_ls_upd_event =
3820 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003821 }
3822
3823 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003824 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003825
paul718e3742002-12-13 20:15:29 +00003826 return 0;
3827}
3828
3829void
hasso52dc7ee2004-09-23 19:18:23 +00003830ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003831{
3832 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003833 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003834 struct prefix_ipv4 p;
3835 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003836 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003837
3838 oi = nbr->oi;
3839
3840 p.family = AF_INET;
3841 p.prefixlen = IPV4_MAX_BITLEN;
3842
3843 /* Decide destination address. */
3844 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3845 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003846 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3847 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003848 else if (flag == OSPF_SEND_PACKET_DIRECT)
3849 p.prefix = nbr->address.u.prefix4;
3850 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3851 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003852 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3853 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003854 else
3855 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3856
3857 if (oi->type == OSPF_IFTYPE_NBMA)
3858 {
3859 if (flag == OSPF_SEND_PACKET_INDIRECT)
3860 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3861 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3862 zlog_warn ("* LS-Update is sent to myself.");
3863 }
3864
3865 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3866
3867 if (rn->info == NULL)
3868 rn->info = list_new ();
3869
paul1eb8ef22005-04-07 07:30:20 +00003870 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003871 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003872
3873 if (oi->t_ls_upd_event == NULL)
3874 oi->t_ls_upd_event =
3875 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3876}
3877
3878static void
hasso52dc7ee2004-09-23 19:18:23 +00003879ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3880 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003881{
3882 struct ospf_packet *op;
3883 u_int16_t length = OSPF_HEADER_SIZE;
3884
3885 op = ospf_packet_new (oi->ifp->mtu);
3886
3887 /* Prepare OSPF common header. */
3888 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3889
3890 /* Prepare OSPF Link State Acknowledgment body. */
3891 length += ospf_make_ls_ack (oi, ack, op->s);
3892
3893 /* Fill OSPF header. */
3894 ospf_fill_header (oi, op->s, length);
3895
3896 /* Set packet length. */
3897 op->length = length;
3898
3899 /* Set destination IP address. */
3900 op->dst = dst;
3901
3902 /* Add packet to the interface output queue. */
3903 ospf_packet_add (oi, op);
3904
3905 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003906 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003907}
3908
3909static int
3910ospf_ls_ack_send_event (struct thread *thread)
3911{
3912 struct ospf_interface *oi = THREAD_ARG (thread);
3913
3914 oi->t_ls_ack_direct = NULL;
3915
3916 while (listcount (oi->ls_ack_direct.ls_ack))
3917 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3918 oi->ls_ack_direct.dst);
3919
3920 return 0;
3921}
3922
3923void
3924ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3925{
3926 struct ospf_interface *oi = nbr->oi;
3927
3928 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3929 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3930
3931 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3932
3933 if (oi->t_ls_ack_direct == NULL)
3934 oi->t_ls_ack_direct =
3935 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3936}
3937
3938/* Send Link State Acknowledgment delayed. */
3939void
3940ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3941{
3942 struct in_addr dst;
3943
3944 /* Decide destination address. */
3945 /* RFC2328 Section 13.5 On non-broadcast
3946 networks, delayed Link State Acknowledgment packets must be
3947 unicast separately over each adjacency (i.e., neighbor whose
3948 state is >= Exchange). */
3949 if (oi->type == OSPF_IFTYPE_NBMA)
3950 {
3951 struct ospf_neighbor *nbr;
3952 struct route_node *rn;
3953
3954 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3955 if ((nbr = rn->info) != NULL)
3956 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3957 while (listcount (oi->ls_ack))
3958 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3959 return;
3960 }
3961 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3962 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3963 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3964 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3965 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3966 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003967 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3968 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003969 else
3970 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3971
3972 while (listcount (oi->ls_ack))
3973 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3974}