blob: b97e3a79b65abf3289992ce5062161097f3bee8f [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);
paul718e3742002-12-13 20:15:29 +0000763
764 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000765 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000766 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000767 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000768 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000769
paul718e3742002-12-13 20:15:29 +0000770 /* Show debug sending packet. */
771 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
772 {
773 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
774 {
ajs2a42e282004-12-08 18:43:03 +0000775 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000776 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000777 stream_set_getp (op->s, 0);
778 ospf_packet_dump (op->s);
779 }
780
ajs2a42e282004-12-08 18:43:03 +0000781 zlog_debug ("%s sent to [%s] via [%s].",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400782 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
paul718e3742002-12-13 20:15:29 +0000783 IF_NAME (oi));
784
785 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000786 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000787 }
788
789 /* Now delete packet from queue. */
790 ospf_packet_delete (oi);
791
Dinesh G Dutt1c063342014-09-30 13:04:45 -0700792 /* Move this interface to the tail of write_q to
793 serve everyone in a round robin fashion */
Paul Jakma6d831132014-10-09 16:05:15 +0100794 listnode_move_to_tail (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000795 if (ospf_fifo_head (oi->obuf) == NULL)
796 {
797 oi->on_write_q = 0;
Paul Jakma6d831132014-10-09 16:05:15 +0100798 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000799 }
800
801 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000802 if (!list_isempty (ospf->oi_write_q))
803 ospf->t_write =
804 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000805
806 return 0;
807}
808
809/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000810static void
paul718e3742002-12-13 20:15:29 +0000811ospf_hello (struct ip *iph, struct ospf_header *ospfh,
812 struct stream * s, struct ospf_interface *oi, int size)
813{
814 struct ospf_hello *hello;
815 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000816 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000817 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000818
819 /* increment statistics. */
820 oi->hello_in++;
821
822 hello = (struct ospf_hello *) STREAM_PNT (s);
823
824 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000825 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000826 {
827 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
828 {
ajs2a42e282004-12-08 18:43:03 +0000829 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000830 "dropping.",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400831 LOOKUP (ospf_packet_type_str, ospfh->type),
pauld3241812003-09-29 12:42:39 +0000832 inet_ntoa (iph->ip_src));
833 }
834 return;
835 }
paul718e3742002-12-13 20:15:29 +0000836
paul718e3742002-12-13 20:15:29 +0000837 /* get neighbor prefix. */
838 p.family = AF_INET;
839 p.prefixlen = ip_masklen (hello->network_mask);
840 p.u.prefix4 = iph->ip_src;
841
842 /* Compare network mask. */
843 /* Checking is ignored for Point-to-Point and Virtual link. */
844 if (oi->type != OSPF_IFTYPE_POINTOPOINT
845 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
846 if (oi->address->prefixlen != p.prefixlen)
847 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000848 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
849 inet_ntoa(ospfh->router_id), IF_NAME(oi),
850 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000851 return;
852 }
853
paul718e3742002-12-13 20:15:29 +0000854 /* Compare Router Dead Interval. */
855 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
856 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000857 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
858 "(expected %u, but received %u).",
859 inet_ntoa(ospfh->router_id),
860 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000861 return;
862 }
863
paulf9ad9372005-10-21 00:45:17 +0000864 /* Compare Hello Interval - ignored if fast-hellos are set. */
865 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
866 {
867 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
868 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000869 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
870 "(expected %u, but received %u).",
871 inet_ntoa(ospfh->router_id),
872 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000873 return;
874 }
875 }
876
paul718e3742002-12-13 20:15:29 +0000877 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000878 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000879 inet_ntoa (ospfh->router_id),
880 ospf_options_dump (hello->options));
881
882 /* Compare options. */
883#define REJECT_IF_TBIT_ON 1 /* XXX */
884#ifdef REJECT_IF_TBIT_ON
885 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
886 {
887 /*
888 * This router does not support non-zero TOS.
889 * Drop this Hello packet not to establish neighbor relationship.
890 */
891 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
892 inet_ntoa (ospfh->router_id));
893 return;
894 }
895#endif /* REJECT_IF_TBIT_ON */
896
897#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000898 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000899 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
900 {
901 /*
902 * This router does know the correct usage of O-bit
903 * the bit should be set in DD packet only.
904 */
905 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
906 inet_ntoa (ospfh->router_id));
907#ifdef STRICT_OBIT_USAGE_CHECK
908 return; /* Reject this packet. */
909#else /* STRICT_OBIT_USAGE_CHECK */
910 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
911#endif /* STRICT_OBIT_USAGE_CHECK */
912 }
913#endif /* HAVE_OPAQUE_LSA */
914
915 /* new for NSSA is to ensure that NP is on and E is off */
916
paul718e3742002-12-13 20:15:29 +0000917 if (oi->area->external_routing == OSPF_AREA_NSSA)
918 {
919 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
920 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
921 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
922 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
923 {
924 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
925 return;
926 }
927 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000928 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000929 }
930 else
paul718e3742002-12-13 20:15:29 +0000931 /* The setting of the E-bit found in the Hello Packet's Options
932 field must match this area's ExternalRoutingCapability A
933 mismatch causes processing to stop and the packet to be
934 dropped. The setting of the rest of the bits in the Hello
935 Packet's Options field should be ignored. */
936 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
937 CHECK_FLAG (hello->options, OSPF_OPTION_E))
938 {
ajs3aa8d5f2004-12-11 18:00:06 +0000939 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
940 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000941 return;
942 }
paul718e3742002-12-13 20:15:29 +0000943
pauld3f0d622004-05-05 15:27:15 +0000944 /* get neighbour struct */
945 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
946
947 /* neighbour must be valid, ospf_nbr_get creates if none existed */
948 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000949
950 old_state = nbr->state;
951
952 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000953 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000954
955 /* RFC2328 Section 9.5.1
956 If the router is not eligible to become Designated Router,
957 (snip) It must also send an Hello Packet in reply to an
958 Hello Packet received from any eligible neighbor (other than
959 the current Designated Router and Backup Designated Router). */
960 if (oi->type == OSPF_IFTYPE_NBMA)
961 if (PRIORITY(oi) == 0 && hello->priority > 0
962 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
963 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
964 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
965 OSPF_HELLO_REPLY_DELAY);
966
967 /* on NBMA network type, it happens to receive bidirectional Hello packet
968 without advance 1-Way Received event.
969 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
970 if (oi->type == OSPF_IFTYPE_NBMA &&
971 (old_state == NSM_Down || old_state == NSM_Attempt))
972 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000973 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000974 nbr->priority = hello->priority;
975 nbr->d_router = hello->d_router;
976 nbr->bd_router = hello->bd_router;
977 return;
978 }
979
paul68980082003-03-25 05:07:42 +0000980 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000981 size - OSPF_HELLO_MIN_SIZE))
982 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000983 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000984 nbr->options |= hello->options;
985 }
986 else
987 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000988 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000989 /* Set neighbor information. */
990 nbr->priority = hello->priority;
991 nbr->d_router = hello->d_router;
992 nbr->bd_router = hello->bd_router;
993 return;
994 }
995
996 /* If neighbor itself declares DR and no BDR exists,
997 cause event BackupSeen */
998 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
999 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
1000 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
1001
1002 /* neighbor itself declares BDR. */
1003 if (oi->state == ISM_Waiting &&
1004 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
1005 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
1006
1007 /* had not previously. */
1008 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
1009 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
1010 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
1011 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
1012 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1013
1014 /* had not previously. */
1015 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
1016 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
1017 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
1018 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
1019 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1020
1021 /* Neighbor priority check. */
1022 if (nbr->priority >= 0 && nbr->priority != hello->priority)
1023 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1024
1025 /* Set neighbor information. */
1026 nbr->priority = hello->priority;
1027 nbr->d_router = hello->d_router;
1028 nbr->bd_router = hello->bd_router;
1029}
1030
1031/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +00001032static void
paul718e3742002-12-13 20:15:29 +00001033ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1034 struct ospf_db_desc *dd)
1035{
1036 nbr->last_recv.flags = dd->flags;
1037 nbr->last_recv.options = dd->options;
1038 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1039}
1040
1041/* Process rest of DD packet. */
1042static void
1043ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1044 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1045 u_int16_t size)
1046{
1047 struct ospf_lsa *new, *find;
1048 struct lsa_header *lsah;
1049
paul9985f832005-02-09 15:51:56 +00001050 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001051 for (size -= OSPF_DB_DESC_MIN_SIZE;
1052 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1053 {
1054 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001055 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001056
1057 /* Unknown LS type. */
1058 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1059 {
ajsbec595a2004-11-30 22:38:43 +00001060 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001061 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1062 return;
1063 }
1064
1065#ifdef HAVE_OPAQUE_LSA
1066 if (IS_OPAQUE_LSA (lsah->type)
1067 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1068 {
1069 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1070 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1071 return;
1072 }
1073#endif /* HAVE_OPAQUE_LSA */
1074
1075 switch (lsah->type)
1076 {
1077 case OSPF_AS_EXTERNAL_LSA:
1078#ifdef HAVE_OPAQUE_LSA
1079 case OSPF_OPAQUE_AS_LSA:
1080#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001081 /* Check for stub area. Reject if AS-External from stub but
1082 allow if from NSSA. */
1083 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001084 {
1085 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1086 lsah->type, inet_ntoa (lsah->id),
1087 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1088 "STUB" : "NSSA");
1089 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1090 return;
1091 }
1092 break;
1093 default:
1094 break;
1095 }
1096
1097 /* Create LS-request object. */
1098 new = ospf_ls_request_new (lsah);
1099
1100 /* Lookup received LSA, then add LS request list. */
1101 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001102
1103 /* ospf_lsa_more_recent is fine with NULL pointers */
1104 switch (ospf_lsa_more_recent (find, new))
1105 {
1106 case -1:
1107 /* Neighbour has a more recent LSA, we must request it */
1108 ospf_ls_request_add (nbr, new);
1109 case 0:
1110 /* If we have a copy of this LSA, it's either less recent
1111 * and we're requesting it from neighbour (the case above), or
1112 * it's as recent and we both have same copy (this case).
1113 *
1114 * In neither of these two cases is there any point in
1115 * describing our copy of the LSA to the neighbour in a
1116 * DB-Summary packet, if we're still intending to do so.
1117 *
1118 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1119 * backward compatible optimisation to OSPF DB Exchange /
1120 * DB Description process implemented here.
1121 */
1122 if (find)
1123 ospf_lsdb_delete (&nbr->db_sum, find);
1124 ospf_lsa_discard (new);
1125 break;
1126 default:
1127 /* We have the more recent copy, nothing specific to do:
1128 * - no need to request neighbours stale copy
1129 * - must leave DB summary list copy alone
1130 */
1131 if (IS_DEBUG_OSPF_EVENT)
1132 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1133 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1134 ospf_lsa_discard (new);
1135 }
paul718e3742002-12-13 20:15:29 +00001136 }
1137
1138 /* Master */
1139 if (IS_SET_DD_MS (nbr->dd_flags))
1140 {
1141 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001142
1143 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001144 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1145 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1146 else
paul718e3742002-12-13 20:15:29 +00001147 ospf_db_desc_send (nbr);
1148 }
1149 /* Slave */
1150 else
1151 {
1152 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1153
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001154 /* Send DD packet in reply.
1155 *
1156 * Must be done to acknowledge the Master's DD, regardless of
1157 * whether we have more LSAs ourselves to describe.
1158 *
1159 * This function will clear the 'More' bit, if after this DD
1160 * we have no more LSAs to describe to the master..
1161 */
paul718e3742002-12-13 20:15:29 +00001162 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001163
1164 /* Slave can raise ExchangeDone now, if master is also done */
1165 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1166 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001167 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001168
paul718e3742002-12-13 20:15:29 +00001169 /* Save received neighbor values from DD. */
1170 ospf_db_desc_save_current (nbr, dd);
1171}
1172
paul4dadc292005-05-06 21:37:42 +00001173static int
paul718e3742002-12-13 20:15:29 +00001174ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1175{
1176 /* Is DD duplicated? */
1177 if (dd->options == nbr->last_recv.options &&
1178 dd->flags == nbr->last_recv.flags &&
1179 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1180 return 1;
1181
1182 return 0;
1183}
1184
1185/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001186static void
paul718e3742002-12-13 20:15:29 +00001187ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1188 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1189{
1190 struct ospf_db_desc *dd;
1191 struct ospf_neighbor *nbr;
1192
1193 /* Increment statistics. */
1194 oi->db_desc_in++;
1195
1196 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001197
pauld3f0d622004-05-05 15:27:15 +00001198 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001199 if (nbr == NULL)
1200 {
1201 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1202 inet_ntoa (ospfh->router_id));
1203 return;
1204 }
1205
1206 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001207 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1208 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001209 {
ajs3aa8d5f2004-12-11 18:00:06 +00001210 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1211 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1212 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001213 return;
1214 }
1215
pauld363df22003-06-19 00:26:34 +00001216 /*
1217 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1218 * required. In fact at least JunOS sends DD packets with P bit clear.
1219 * Until proper solution is developped, this hack should help.
1220 *
1221 * Update: According to the RFCs, N bit is specified /only/ for Hello
1222 * options, unfortunately its use in DD options is not specified. Hence some
1223 * implementations follow E-bit semantics and set it in DD options, and some
1224 * treat it as unspecified and hence follow the directive "default for
1225 * options is clear", ie unset.
1226 *
1227 * Reset the flag, as ospfd follows E-bit semantics.
1228 */
1229 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1230 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1231 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1232 {
1233 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001234 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001235 inet_ntoa (nbr->router_id) );
1236 SET_FLAG (dd->options, OSPF_OPTION_NP);
1237 }
pauld363df22003-06-19 00:26:34 +00001238
paul718e3742002-12-13 20:15:29 +00001239#ifdef REJECT_IF_TBIT_ON
1240 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1241 {
1242 /*
1243 * In Hello protocol, optional capability must have checked
1244 * to prevent this T-bit enabled router be my neighbor.
1245 */
1246 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1247 return;
1248 }
1249#endif /* REJECT_IF_TBIT_ON */
1250
1251#ifdef HAVE_OPAQUE_LSA
1252 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001253 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001254 {
1255 /*
1256 * This node is not configured to handle O-bit, for now.
1257 * Clear it to ignore unsupported capability proposed by neighbor.
1258 */
1259 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1260 }
1261#endif /* HAVE_OPAQUE_LSA */
1262
Paul Jakma57c5c652010-01-07 06:12:53 +00001263 /* Add event to thread. */
1264 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1265
paul718e3742002-12-13 20:15:29 +00001266 /* Process DD packet by neighbor status. */
1267 switch (nbr->state)
1268 {
1269 case NSM_Down:
1270 case NSM_Attempt:
1271 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001272 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001273 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001274 LOOKUP (ospf_nsm_state_msg, nbr->state));
1275 break;
1276 case NSM_Init:
1277 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1278 /* If the new state is ExStart, the processing of the current
1279 packet should then continue in this new state by falling
1280 through to case ExStart below. */
1281 if (nbr->state != NSM_ExStart)
1282 break;
1283 case NSM_ExStart:
1284 /* Initial DBD */
1285 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1286 (size == OSPF_DB_DESC_MIN_SIZE))
1287 {
paul68980082003-03-25 05:07:42 +00001288 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001289 {
1290 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001291 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001292 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001293 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001294
1295 /* Reset I/MS */
1296 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001297 }
1298 else
1299 {
1300 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001301 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001302 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001303 break;
1304 }
1305 }
1306 /* Ack from the Slave */
1307 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1308 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001309 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001310 {
ajs17eaa722004-12-29 21:04:48 +00001311 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001312 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001313 /* Reset I, leaving MS */
1314 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001315 }
1316 else
1317 {
ajs3aa8d5f2004-12-11 18:00:06 +00001318 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1319 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001320 break;
1321 }
1322
1323 /* This is where the real Options are saved */
1324 nbr->options = dd->options;
1325
1326#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001327 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001328 {
1329 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001330 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001331 inet_ntoa (nbr->router_id),
1332 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1333
1334 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1335 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1336 {
paul6d452762005-11-03 11:15:44 +00001337 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1338 "Opaque-LSAs cannot be reliably advertised "
1339 "in this network.",
1340 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001341 /* This situation is undesirable, but not a real error. */
1342 }
1343 }
1344#endif /* HAVE_OPAQUE_LSA */
1345
1346 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1347
1348 /* continue processing rest of packet. */
1349 ospf_db_desc_proc (s, oi, nbr, dd, size);
1350 break;
1351 case NSM_Exchange:
1352 if (ospf_db_desc_is_dup (dd, nbr))
1353 {
1354 if (IS_SET_DD_MS (nbr->dd_flags))
1355 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001356 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001357 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001358 else
1359 /* Slave: cause to retransmit the last Database Description. */
1360 {
paul6d452762005-11-03 11:15:44 +00001361 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001362 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001363 ospf_db_desc_resend (nbr);
1364 }
1365 break;
1366 }
1367
1368 /* Otherwise DD packet should be checked. */
1369 /* Check Master/Slave bit mismatch */
1370 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1371 {
ajs3aa8d5f2004-12-11 18:00:06 +00001372 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1373 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001374 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1375 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001376 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001377 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001378 break;
1379 }
1380
1381 /* Check initialize bit is set. */
1382 if (IS_SET_DD_I (dd->flags))
1383 {
paul6d452762005-11-03 11:15:44 +00001384 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001385 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001386 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1387 break;
1388 }
1389
1390 /* Check DD Options. */
1391 if (dd->options != nbr->options)
1392 {
1393#ifdef ORIGINAL_CODING
1394 /* Save the new options for debugging */
1395 nbr->options = dd->options;
1396#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001397 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1398 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001399 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1400 break;
1401 }
1402
1403 /* Check DD sequence number. */
1404 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1405 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1406 (!IS_SET_DD_MS (nbr->dd_flags) &&
1407 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1408 {
ajs3aa8d5f2004-12-11 18:00:06 +00001409 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1410 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001411 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1412 break;
1413 }
1414
1415 /* Continue processing rest of packet. */
1416 ospf_db_desc_proc (s, oi, nbr, dd, size);
1417 break;
1418 case NSM_Loading:
1419 case NSM_Full:
1420 if (ospf_db_desc_is_dup (dd, nbr))
1421 {
1422 if (IS_SET_DD_MS (nbr->dd_flags))
1423 {
1424 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001425 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1426 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001427 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001428 break;
1429 }
1430 else
1431 {
1432 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001433 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001434 t = tv_sub (now, nbr->last_send_ts);
1435 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1436 {
1437 /* In states Loading and Full the slave must resend
1438 its last Database Description packet in response to
1439 duplicate Database Description packets received
1440 from the master. For this reason the slave must
1441 wait RouterDeadInterval seconds before freeing the
1442 last Database Description packet. Reception of a
1443 Database Description packet from the master after
1444 this interval will generate a SeqNumberMismatch
1445 neighbor event. RFC2328 Section 10.8 */
1446 ospf_db_desc_resend (nbr);
1447 break;
1448 }
1449 }
1450 }
1451
1452 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1453 break;
1454 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001455 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1456 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001457 break;
1458 }
1459}
1460
1461#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1462
1463/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001464static void
paul718e3742002-12-13 20:15:29 +00001465ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1466 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1467{
1468 struct ospf_neighbor *nbr;
1469 u_int32_t ls_type;
1470 struct in_addr ls_id;
1471 struct in_addr adv_router;
1472 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001473 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001474 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001475
1476 /* Increment statistics. */
1477 oi->ls_req_in++;
1478
pauld3f0d622004-05-05 15:27:15 +00001479 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001480 if (nbr == NULL)
1481 {
1482 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1483 inet_ntoa (ospfh->router_id));
1484 return;
1485 }
1486
Paul Jakma57c5c652010-01-07 06:12:53 +00001487 /* Add event to thread. */
1488 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1489
paul718e3742002-12-13 20:15:29 +00001490 /* Neighbor State should be Exchange or later. */
1491 if (nbr->state != NSM_Exchange &&
1492 nbr->state != NSM_Loading &&
1493 nbr->state != NSM_Full)
1494 {
ajsbec595a2004-11-30 22:38:43 +00001495 zlog_warn ("Link State Request received from %s: "
1496 "Neighbor state is %s, packet discarded.",
1497 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001498 LOOKUP (ospf_nsm_state_msg, nbr->state));
1499 return;
1500 }
1501
1502 /* Send Link State Update for ALL requested LSAs. */
1503 ls_upd = list_new ();
1504 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1505
1506 while (size >= OSPF_LSA_KEY_SIZE)
1507 {
1508 /* Get one slice of Link State Request. */
1509 ls_type = stream_getl (s);
1510 ls_id.s_addr = stream_get_ipv4 (s);
1511 adv_router.s_addr = stream_get_ipv4 (s);
1512
1513 /* Verify LSA type. */
1514 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1515 {
1516 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1517 list_delete (ls_upd);
1518 return;
1519 }
1520
1521 /* Search proper LSA in LSDB. */
1522 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1523 if (find == NULL)
1524 {
1525 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1526 list_delete (ls_upd);
1527 return;
1528 }
1529
gdt86f1fd92005-01-10 14:20:43 +00001530 /* Packet overflows MTU size, send immediately. */
1531 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001532 {
1533 if (oi->type == OSPF_IFTYPE_NBMA)
1534 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1535 else
1536 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1537
1538 /* Only remove list contents. Keep ls_upd. */
1539 list_delete_all_node (ls_upd);
1540
1541 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1542 }
1543
1544 /* Append LSA to update list. */
1545 listnode_add (ls_upd, find);
1546 length += ntohs (find->data->length);
1547
1548 size -= OSPF_LSA_KEY_SIZE;
1549 }
1550
1551 /* Send rest of Link State Update. */
1552 if (listcount (ls_upd) > 0)
1553 {
1554 if (oi->type == OSPF_IFTYPE_NBMA)
1555 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1556 else
1557 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1558
1559 list_delete (ls_upd);
1560 }
1561 else
1562 list_free (ls_upd);
1563}
1564
1565/* Get the list of LSAs from Link State Update packet.
1566 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001567static struct list *
paul718e3742002-12-13 20:15:29 +00001568ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1569 struct ospf_interface *oi, size_t size)
1570{
1571 u_int16_t count, sum;
1572 u_int32_t length;
1573 struct lsa_header *lsah;
1574 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001575 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001576
1577 lsas = list_new ();
1578
1579 count = stream_getl (s);
1580 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1581
1582 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001583 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001584 {
1585 lsah = (struct lsa_header *) STREAM_PNT (s);
1586 length = ntohs (lsah->length);
1587
1588 if (length > size)
1589 {
1590 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1591 break;
1592 }
1593
1594 /* Validate the LSA's LS checksum. */
1595 sum = lsah->checksum;
JR Riversd8a4e422012-09-13 17:17:36 +00001596 if (! ospf_lsa_checksum_valid (lsah))
paul718e3742002-12-13 20:15:29 +00001597 {
Jaroslav Fojtik223da1a2011-12-11 18:22:16 +04001598 /* (bug #685) more details in a one-line message make it possible
1599 * to identify problem source on the one hand and to have a better
1600 * chance to compress repeated messages in syslog on the other */
1601 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1602 sum, lsah->checksum, inet_ntoa (lsah->id),
1603 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1604 inet_ntoa (lsah->adv_router));
paul718e3742002-12-13 20:15:29 +00001605 continue;
1606 }
1607
1608 /* Examine the LSA's LS type. */
1609 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1610 {
1611 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1612 continue;
1613 }
1614
1615 /*
1616 * What if the received LSA's age is greater than MaxAge?
1617 * Treat it as a MaxAge case -- endo.
1618 */
1619 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1620 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1621
1622#ifdef HAVE_OPAQUE_LSA
1623 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1624 {
1625#ifdef STRICT_OBIT_USAGE_CHECK
1626 if ((IS_OPAQUE_LSA(lsah->type) &&
1627 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1628 || (! IS_OPAQUE_LSA(lsah->type) &&
1629 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1630 {
1631 /*
1632 * This neighbor must know the exact usage of O-bit;
1633 * the bit will be set in Type-9,10,11 LSAs only.
1634 */
1635 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1636 continue;
1637 }
1638#endif /* STRICT_OBIT_USAGE_CHECK */
1639
1640 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1641 if (lsah->type == OSPF_OPAQUE_AS_LSA
1642 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1643 {
1644 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001645 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 +00001646 continue;
1647 }
1648 }
1649 else if (IS_OPAQUE_LSA(lsah->type))
1650 {
1651 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1652 continue;
1653 }
1654#endif /* HAVE_OPAQUE_LSA */
1655
1656 /* Create OSPF LSA instance. */
1657 lsa = ospf_lsa_new ();
1658
1659 /* We may wish to put some error checking if type NSSA comes in
1660 and area not in NSSA mode */
1661 switch (lsah->type)
1662 {
1663 case OSPF_AS_EXTERNAL_LSA:
1664#ifdef HAVE_OPAQUE_LSA
1665 case OSPF_OPAQUE_AS_LSA:
Christian Franke58952492013-02-20 10:00:53 +00001666#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001667 lsa->area = NULL;
1668 break;
Christian Franke58952492013-02-20 10:00:53 +00001669#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001670 case OSPF_OPAQUE_LINK_LSA:
1671 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1672 /* Fallthrough */
1673#endif /* HAVE_OPAQUE_LSA */
1674 default:
1675 lsa->area = oi->area;
1676 break;
1677 }
1678
1679 lsa->data = ospf_lsa_data_new (length);
1680 memcpy (lsa->data, lsah, length);
1681
1682 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001683 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
David Lampartereed3c482015-03-03 08:51:53 +01001684 lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa);
paul718e3742002-12-13 20:15:29 +00001685 listnode_add (lsas, lsa);
1686 }
1687
1688 return lsas;
1689}
1690
1691/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001692static void
hasso52dc7ee2004-09-23 19:18:23 +00001693ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001694{
paul1eb8ef22005-04-07 07:30:20 +00001695 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001696 struct ospf_lsa *lsa;
1697
paul1eb8ef22005-04-07 07:30:20 +00001698 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1699 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001700
1701 list_delete (lsas);
1702}
1703
1704/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001705static void
paul718e3742002-12-13 20:15:29 +00001706ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1707 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1708{
1709 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001710 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001711 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001712 struct ospf_lsa *lsa = NULL;
1713 /* unsigned long ls_req_found = 0; */
1714
1715 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1716
1717 /* Increment statistics. */
1718 oi->ls_upd_in++;
1719
1720 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001721 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001722 if (nbr == NULL)
1723 {
1724 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1725 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1726 return;
1727 }
1728
Paul Jakma57c5c652010-01-07 06:12:53 +00001729 /* Add event to thread. */
1730 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1731
paul718e3742002-12-13 20:15:29 +00001732 /* Check neighbor state. */
1733 if (nbr->state < NSM_Exchange)
1734 {
ajs3aa8d5f2004-12-11 18:00:06 +00001735 zlog_warn ("Link State Update: "
1736 "Neighbor[%s] state %s is less than Exchange",
1737 inet_ntoa (ospfh->router_id),
1738 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001739 return;
1740 }
1741
1742 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1743 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1744 * of section 13.
1745 */
1746 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1747
1748#ifdef HAVE_OPAQUE_LSA
1749 /*
paul718e3742002-12-13 20:15:29 +00001750 * If self-originated Opaque-LSAs that have flooded before restart
1751 * are contained in the received LSUpd message, corresponding LSReq
1752 * messages to be sent may have to be modified.
1753 * To eliminate possible race conditions such that flushing and normal
1754 * updating for the same LSA would take place alternately, this trick
1755 * must be done before entering to the loop below.
1756 */
paul69310a62005-05-11 18:09:59 +00001757 /* XXX: Why is this Opaque specific? Either our core code is deficient
1758 * and this should be fixed generally, or Opaque is inventing strawman
1759 * problems */
paul718e3742002-12-13 20:15:29 +00001760 ospf_opaque_adjust_lsreq (nbr, lsas);
1761#endif /* HAVE_OPAQUE_LSA */
1762
1763#define DISCARD_LSA(L,N) {\
1764 if (IS_DEBUG_OSPF_EVENT) \
David Lampartereed3c482015-03-03 08:51:53 +01001765 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p" \
1766 " Type-%d", N, (void *)lsa, (int) lsa->data->type); \
paul718e3742002-12-13 20:15:29 +00001767 ospf_lsa_discard (L); \
1768 continue; }
1769
Andrew Certainf92c57f2012-12-04 13:29:21 -08001770 /* Process each LSA received in the one packet.
1771 *
1772 * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
Andrew Certain0798cee2012-12-04 13:43:42 -08001773 * text below are from the steps in RFC 2328, Section 13.
Andrew Certainf92c57f2012-12-04 13:29:21 -08001774 */
paul1eb8ef22005-04-07 07:30:20 +00001775 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001776 {
1777 struct ospf_lsa *ls_ret, *current;
1778 int ret = 1;
1779
paul718e3742002-12-13 20:15:29 +00001780 if (IS_DEBUG_OSPF_NSSA)
1781 {
1782 char buf1[INET_ADDRSTRLEN];
1783 char buf2[INET_ADDRSTRLEN];
1784 char buf3[INET_ADDRSTRLEN];
1785
ajs2a42e282004-12-08 18:43:03 +00001786 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001787 lsa->data->type,
1788 inet_ntop (AF_INET, &ospfh->router_id,
1789 buf1, INET_ADDRSTRLEN),
1790 inet_ntop (AF_INET, &lsa->data->id,
1791 buf2, INET_ADDRSTRLEN),
1792 inet_ntop (AF_INET, &lsa->data->adv_router,
1793 buf3, INET_ADDRSTRLEN));
1794 }
paul718e3742002-12-13 20:15:29 +00001795
1796 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1797
Andrew Certainf92c57f2012-12-04 13:29:21 -08001798 /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
paul718e3742002-12-13 20:15:29 +00001799
Andrew Certainf92c57f2012-12-04 13:29:21 -08001800 /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
paul718e3742002-12-13 20:15:29 +00001801
Andrew Certainf92c57f2012-12-04 13:29:21 -08001802 /* (3) Do not take in AS External LSAs if we are a stub or NSSA. */
paul718e3742002-12-13 20:15:29 +00001803
1804 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1805
1806 /* Do take in Type-7's if we are an NSSA */
1807
1808 /* If we are also an ABR, later translate them to a Type-5 packet */
1809
1810 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1811 translate them to a separate Type-5 packet. */
1812
1813 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1814 /* Reject from STUB or NSSA */
1815 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1816 {
paul718e3742002-12-13 20:15:29 +00001817 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001818 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001819 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001820 }
1821
paul718e3742002-12-13 20:15:29 +00001822 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1823 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1824 {
paul718e3742002-12-13 20:15:29 +00001825 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001826 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001827 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001828 }
paul718e3742002-12-13 20:15:29 +00001829
David Lamparter23cd8fb2013-08-02 07:27:53 +00001830 /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */
1831 if (lsa->data->type == OSPF_ROUTER_LSA)
1832 if (!IPV4_ADDR_SAME(&lsa->data->id, &lsa->data->adv_router))
1833 {
1834 char buf1[INET_ADDRSTRLEN];
1835 char buf2[INET_ADDRSTRLEN];
1836 char buf3[INET_ADDRSTRLEN];
1837
1838 zlog_err("Incoming Router-LSA from %s with "
1839 "Adv-ID[%s] != LS-ID[%s]",
1840 inet_ntop (AF_INET, &ospfh->router_id,
1841 buf1, INET_ADDRSTRLEN),
1842 inet_ntop (AF_INET, &lsa->data->id,
1843 buf2, INET_ADDRSTRLEN),
1844 inet_ntop (AF_INET, &lsa->data->adv_router,
1845 buf3, INET_ADDRSTRLEN));
1846 zlog_err("OSPF domain compromised by attack or corruption. "
1847 "Verify correct operation of -ALL- OSPF routers.");
1848 DISCARD_LSA (lsa, 0);
1849 }
1850
paul718e3742002-12-13 20:15:29 +00001851 /* Find the LSA in the current database. */
1852
1853 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1854
Andrew Certainf92c57f2012-12-04 13:29:21 -08001855 /* (4) If the LSA's LS age is equal to MaxAge, and there is currently
paul718e3742002-12-13 20:15:29 +00001856 no instance of the LSA in the router's link state database,
1857 and none of router's neighbors are in states Exchange or Loading,
Andrew Certainf92c57f2012-12-04 13:29:21 -08001858 then take the following actions: */
paul718e3742002-12-13 20:15:29 +00001859
1860 if (IS_LSA_MAXAGE (lsa) && !current &&
Christian Franke4c14b7f2013-02-20 10:00:54 +00001861 ospf_check_nbr_status(oi->ospf))
paul718e3742002-12-13 20:15:29 +00001862 {
Andrew Certainf92c57f2012-12-04 13:29:21 -08001863 /* (4a) Response Link State Acknowledgment. */
paul718e3742002-12-13 20:15:29 +00001864 ospf_ls_ack_send (nbr, lsa);
1865
Andrew Certainf92c57f2012-12-04 13:29:21 -08001866 /* (4b) Discard LSA. */
Ayan Banerjeefaf98752012-12-04 10:49:12 -08001867 if (IS_DEBUG_OSPF (lsa, LSA))
1868 {
1869 zlog_debug ("Link State Update[%s]: LS age is equal to MaxAge.",
1870 dump_lsa_key(lsa));
1871 }
paul718e3742002-12-13 20:15:29 +00001872 DISCARD_LSA (lsa, 3);
1873 }
1874
1875#ifdef HAVE_OPAQUE_LSA
1876 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001877 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001878 {
1879 /*
1880 * Even if initial flushing seems to be completed, there might
1881 * be a case that self-originated LSA with MaxAge still remain
1882 * in the routing domain.
1883 * Just send an LSAck message to cease retransmission.
1884 */
1885 if (IS_LSA_MAXAGE (lsa))
1886 {
1887 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1888 ospf_ls_ack_send (nbr, lsa);
1889 ospf_lsa_discard (lsa);
1890
1891 if (current != NULL && ! IS_LSA_MAXAGE (current))
1892 ospf_opaque_lsa_refresh_schedule (current);
1893 continue;
1894 }
1895
1896 /*
1897 * If an instance of self-originated Opaque-LSA is not found
1898 * in the LSDB, there are some possible cases here.
1899 *
1900 * 1) This node lost opaque-capability after restart.
1901 * 2) Else, a part of opaque-type is no more supported.
1902 * 3) Else, a part of opaque-id is no more supported.
1903 *
1904 * Anyway, it is still this node's responsibility to flush it.
1905 * Otherwise, the LSA instance remains in the routing domain
1906 * until its age reaches to MaxAge.
1907 */
paul69310a62005-05-11 18:09:59 +00001908 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001909 if (current == NULL)
1910 {
1911 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001912 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1913 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001914
1915 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001916
1917 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1918 ospf_ls_ack_send (nbr, lsa);
1919
paul718e3742002-12-13 20:15:29 +00001920 continue;
1921 }
1922 }
1923#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001924
hassocb05eb22004-02-11 21:10:19 +00001925 /* It might be happen that received LSA is self-originated network LSA, but
Andrew Certainf92c57f2012-12-04 13:29:21 -08001926 * router ID is changed. So, we should check if LSA is a network-LSA whose
hassocb05eb22004-02-11 21:10:19 +00001927 * Link State ID is one of the router's own IP interface addresses but whose
1928 * Advertising Router is not equal to the router's own Router ID
1929 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1930 */
1931
1932 if(lsa->data->type == OSPF_NETWORK_LSA)
1933 {
paul1eb8ef22005-04-07 07:30:20 +00001934 struct listnode *oinode, *oinnode;
1935 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001936 int Flag = 0;
1937
paul1eb8ef22005-04-07 07:30:20 +00001938 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001939 {
hassocb05eb22004-02-11 21:10:19 +00001940 if(out_if == NULL)
1941 break;
1942
1943 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1944 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1945 {
1946 if(out_if->network_lsa_self)
1947 {
1948 ospf_lsa_flush_area(lsa,out_if->area);
1949 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001950 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
David Lampartereed3c482015-03-03 08:51:53 +01001951 (void *)lsa, (int) lsa->data->type);
hassocb05eb22004-02-11 21:10:19 +00001952 ospf_lsa_discard (lsa);
1953 Flag = 1;
1954 }
1955 break;
1956 }
1957 }
1958 if(Flag)
1959 continue;
1960 }
paul718e3742002-12-13 20:15:29 +00001961
1962 /* (5) Find the instance of this LSA that is currently contained
1963 in the router's link state database. If there is no
1964 database copy, or the received LSA is more recent than
Andrew Certainf92c57f2012-12-04 13:29:21 -08001965 the database copy the following steps must be performed.
1966 (The sub steps from RFC 2328 section 13 step (5) will be performed in
1967 ospf_flood() ) */
paul718e3742002-12-13 20:15:29 +00001968
1969 if (current == NULL ||
1970 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1971 {
1972 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001973 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001974 DISCARD_LSA (lsa, 4);
1975 continue;
1976 }
1977
1978 /* (6) Else, If there is an instance of the LSA on the sending
1979 neighbor's Link state request list, an error has occurred in
1980 the Database Exchange process. In this case, restart the
1981 Database Exchange process by generating the neighbor event
1982 BadLSReq for the sending neighbor and stop processing the
1983 Link State Update packet. */
1984
1985 if (ospf_ls_request_lookup (nbr, lsa))
1986 {
1987 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001988 zlog_warn("LSA[%s] instance exists on Link state request list",
1989 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001990
1991 /* Clean list of LSAs. */
1992 ospf_upd_list_clean (lsas);
1993 /* this lsa is not on lsas list already. */
1994 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001995 return;
1996 }
1997
1998 /* If the received LSA is the same instance as the database copy
1999 (i.e., neither one is more recent) the following two steps
2000 should be performed: */
2001
2002 if (ret == 0)
2003 {
2004 /* If the LSA is listed in the Link state retransmission list
2005 for the receiving adjacency, the router itself is expecting
2006 an acknowledgment for this LSA. The router should treat the
2007 received LSA as an acknowledgment by removing the LSA from
2008 the Link state retransmission list. This is termed an
2009 "implied acknowledgment". */
2010
2011 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
2012
2013 if (ls_ret != NULL)
2014 {
2015 ospf_ls_retransmit_delete (nbr, ls_ret);
2016
2017 /* Delayed acknowledgment sent if advertisement received
2018 from Designated Router, otherwise do nothing. */
2019 if (oi->state == ISM_Backup)
2020 if (NBR_IS_DR (nbr))
2021 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
2022
2023 DISCARD_LSA (lsa, 5);
2024 }
2025 else
2026 /* Acknowledge the receipt of the LSA by sending a
2027 Link State Acknowledgment packet back out the receiving
2028 interface. */
2029 {
2030 ospf_ls_ack_send (nbr, lsa);
2031 DISCARD_LSA (lsa, 6);
2032 }
2033 }
2034
2035 /* The database copy is more recent. If the database copy
2036 has LS age equal to MaxAge and LS sequence number equal to
2037 MaxSequenceNumber, simply discard the received LSA without
2038 acknowledging it. (In this case, the LSA's LS sequence number is
2039 wrapping, and the MaxSequenceNumber LSA must be completely
2040 flushed before any new LSA instance can be introduced). */
2041
2042 else if (ret > 0) /* Database copy is more recent */
2043 {
2044 if (IS_LSA_MAXAGE (current) &&
2045 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
2046 {
2047 DISCARD_LSA (lsa, 7);
2048 }
2049 /* Otherwise, as long as the database copy has not been sent in a
2050 Link State Update within the last MinLSArrival seconds, send the
2051 database copy back to the sending neighbor, encapsulated within
2052 a Link State Update Packet. The Link State Update Packet should
2053 be sent directly to the neighbor. In so doing, do not put the
2054 database copy of the LSA on the neighbor's link state
2055 retransmission list, and do not acknowledge the received (less
2056 recent) LSA instance. */
2057 else
2058 {
2059 struct timeval now;
2060
Paul Jakma2518efd2006-08-27 06:49:29 +00002061 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00002062
2063 if (tv_cmp (tv_sub (now, current->tv_orig),
Paul Jakma2c9f8e32010-01-11 16:22:12 +00002064 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
paul718e3742002-12-13 20:15:29 +00002065 /* Trap NSSA type later.*/
2066 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2067 DISCARD_LSA (lsa, 8);
2068 }
2069 }
2070 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002071#undef DISCARD_LSA
2072
paul718e3742002-12-13 20:15:29 +00002073 assert (listcount (lsas) == 0);
2074 list_delete (lsas);
2075}
2076
2077/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002078static void
paul718e3742002-12-13 20:15:29 +00002079ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2080 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2081{
2082 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002083
paul718e3742002-12-13 20:15:29 +00002084 /* increment statistics. */
2085 oi->ls_ack_in++;
2086
pauld3f0d622004-05-05 15:27:15 +00002087 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002088 if (nbr == NULL)
2089 {
2090 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2091 inet_ntoa (ospfh->router_id));
2092 return;
2093 }
2094
Paul Jakma57c5c652010-01-07 06:12:53 +00002095 /* Add event to thread. */
2096 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2097
paul718e3742002-12-13 20:15:29 +00002098 if (nbr->state < NSM_Exchange)
2099 {
ajs3aa8d5f2004-12-11 18:00:06 +00002100 zlog_warn ("Link State Acknowledgment: "
2101 "Neighbor[%s] state %s is less than Exchange",
2102 inet_ntoa (ospfh->router_id),
2103 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002104 return;
2105 }
paul69310a62005-05-11 18:09:59 +00002106
paul718e3742002-12-13 20:15:29 +00002107 while (size >= OSPF_LSA_HEADER_SIZE)
2108 {
2109 struct ospf_lsa *lsa, *lsr;
2110
2111 lsa = ospf_lsa_new ();
2112 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2113
2114 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2115 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002116 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002117
2118 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2119 {
2120 lsa->data = NULL;
2121 ospf_lsa_discard (lsa);
2122 continue;
2123 }
2124
2125 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2126
Lu Feng49d7af12014-02-21 08:11:15 +00002127 if (lsr != NULL && ospf_lsa_more_recent (lsr, lsa) == 0)
paul718e3742002-12-13 20:15:29 +00002128 {
2129#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002130 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002131 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002132#endif /* HAVE_OPAQUE_LSA */
2133
2134 ospf_ls_retransmit_delete (nbr, lsr);
2135 }
2136
2137 lsa->data = NULL;
2138 ospf_lsa_discard (lsa);
2139 }
2140
paul718e3742002-12-13 20:15:29 +00002141 return;
paul718e3742002-12-13 20:15:29 +00002142}
David Lamparter6b0655a2014-06-04 06:53:35 +02002143
ajs038163f2005-02-17 19:55:59 +00002144static struct stream *
ajs5c333492005-02-23 15:43:01 +00002145ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002146{
2147 int ret;
ajs5c333492005-02-23 15:43:01 +00002148 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002149 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002150 unsigned int ifindex = 0;
2151 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002152 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002153 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002154 struct msghdr msgh;
2155
paul68defd62004-09-27 07:27:13 +00002156 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002157 msgh.msg_iov = &iov;
2158 msgh.msg_iovlen = 1;
2159 msgh.msg_control = (caddr_t) buff;
2160 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002161
ajs5c333492005-02-23 15:43:01 +00002162 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2163 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002164 {
ajs5c333492005-02-23 15:43:01 +00002165 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2166 return NULL;
2167 }
paul69310a62005-05-11 18:09:59 +00002168 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002169 {
2170 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2171 "(ip header size is %u)",
2172 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002173 return NULL;
2174 }
paul18b12c32004-10-05 14:38:29 +00002175
ajs5c333492005-02-23 15:43:01 +00002176 /* Note that there should not be alignment problems with this assignment
2177 because this is at the beginning of the stream data buffer. */
2178 iph = (struct ip *) STREAM_DATA(ibuf);
2179 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002180
ajs5c333492005-02-23 15:43:01 +00002181 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002182
Dmitrij Tejblumde5ccb92011-12-12 20:30:10 +04002183#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
paul718e3742002-12-13 20:15:29 +00002184 /*
2185 * Kernel network code touches incoming IP header parameters,
2186 * before protocol specific processing.
2187 *
2188 * 1) Convert byteorder to host representation.
2189 * --> ip_len, ip_id, ip_off
2190 *
2191 * 2) Adjust ip_len to strip IP header size!
2192 * --> If user process receives entire IP packet via RAW
2193 * socket, it must consider adding IP header size to
2194 * the "ip_len" field of "ip" structure.
2195 *
2196 * For more details, see <netinet/ip_input.c>.
2197 */
ajs5c333492005-02-23 15:43:01 +00002198 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002199#endif
2200
David BÉRARD0150c9c2010-05-11 10:17:53 +02002201#if defined(__DragonFly__)
2202 /*
2203 * in DragonFly's raw socket, ip_len/ip_off are read
2204 * in network byte order.
2205 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2206 */
2207 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2208#endif
2209
paul863082d2004-08-19 04:43:43 +00002210 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002211
2212 *ifp = if_lookup_by_index (ifindex);
2213
2214 if (ret != ip_len)
2215 {
ajs5c333492005-02-23 15:43:01 +00002216 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2217 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002218 return NULL;
2219 }
2220
2221 return ibuf;
2222}
2223
paul4dadc292005-05-06 21:37:42 +00002224static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002225ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002226 struct ip *iph, struct ospf_header *ospfh)
2227{
2228 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002229 struct ospf_vl_data *vl_data;
2230 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002231 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002232
2233 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2234 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002235 return NULL;
paul718e3742002-12-13 20:15:29 +00002236
pauld3f0d622004-05-05 15:27:15 +00002237 /* look for local OSPF interface matching the destination
2238 * to determine Area ID. We presume therefore the destination address
2239 * is unique, or at least (for "unnumbered" links), not used in other
2240 * areas
2241 */
2242 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2243 iph->ip_dst)) == NULL)
2244 return NULL;
paul718e3742002-12-13 20:15:29 +00002245
paul1eb8ef22005-04-07 07:30:20 +00002246 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002247 {
paul020709f2003-04-04 02:44:16 +00002248 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002249 if (!vl_area)
2250 continue;
2251
2252 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2253 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2254 {
2255 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002256 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002257 IF_NAME (vl_data->vl_oi));
2258 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2259 {
2260 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002261 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002262 return NULL;
2263 }
2264
2265 return vl_data->vl_oi;
2266 }
2267 }
2268
2269 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002270 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002271
pauld3f0d622004-05-05 15:27:15 +00002272 return NULL;
paul718e3742002-12-13 20:15:29 +00002273}
2274
Paul Jakmaf63f06d2011-04-08 12:44:43 +01002275static int
paul718e3742002-12-13 20:15:29 +00002276ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2277{
2278 /* Check match the Area ID of the receiving interface. */
2279 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2280 return 1;
2281
2282 return 0;
2283}
2284
2285/* Unbound socket will accept any Raw IP packets if proto is matched.
2286 To prevent it, compare src IP address and i/f address with masking
2287 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002288static int
paul718e3742002-12-13 20:15:29 +00002289ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2290{
2291 struct in_addr mask, me, him;
2292
2293 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2294 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2295 return 1;
2296
2297 masklen2ip (oi->address->prefixlen, &mask);
2298
2299 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2300 him.s_addr = ip_src.s_addr & mask.s_addr;
2301
2302 if (IPV4_ADDR_SAME (&me, &him))
2303 return 1;
2304
2305 return 0;
2306}
2307
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002308/* Return 1, if the packet is properly authenticated and checksummed,
2309 0 otherwise. In particular, check that AuType header field is valid and
2310 matches the locally configured AuType, and that D.5 requirements are met. */
paul4dadc292005-05-06 21:37:42 +00002311static int
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002312ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +00002313{
paul718e3742002-12-13 20:15:29 +00002314 struct crypt_key *ck;
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002315 u_int16_t iface_auth_type;
2316 u_int16_t pkt_auth_type = ntohs (ospfh->auth_type);
paul718e3742002-12-13 20:15:29 +00002317
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002318 switch (pkt_auth_type)
2319 {
2320 case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
2321 if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))
paul718e3742002-12-13 20:15:29 +00002322 {
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002323 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2324 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null",
2325 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2326 return 0;
paul718e3742002-12-13 20:15:29 +00002327 }
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002328 if (! ospf_check_sum (ospfh))
2329 {
2330 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2331 zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s",
2332 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2333 return 0;
2334 }
2335 return 1;
2336 case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */
2337 if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi)))
2338 {
2339 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2340 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple",
2341 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2342 return 0;
2343 }
2344 if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2345 {
2346 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2347 zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi));
2348 return 0;
2349 }
2350 if (! ospf_check_sum (ospfh))
2351 {
2352 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2353 zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s",
2354 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2355 return 0;
2356 }
2357 return 1;
2358 case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */
2359 if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi)))
2360 {
2361 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2362 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2363 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2364 return 0;
2365 }
2366 if (ospfh->checksum)
2367 {
2368 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2369 zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi));
2370 return 0;
2371 }
2372 /* only MD5 crypto method can pass ospf_packet_examin() */
2373 if
2374 (
2375 NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) ||
2376 ospfh->u.crypt.key_id != ck->key_id ||
2377 /* Condition above uses the last key ID on the list, which is
2378 different from what ospf_crypt_key_lookup() does. A bug? */
2379 ! ospf_check_md5_digest (oi, ospfh)
2380 )
2381 {
2382 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2383 zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi));
2384 return 0;
2385 }
2386 return 1;
2387 default:
2388 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2389 zlog_warn ("interface %s: invalid packet auth-type (%02x)",
2390 IF_NAME (oi), pkt_auth_type);
2391 return 0;
2392 }
paul718e3742002-12-13 20:15:29 +00002393}
2394
paul4dadc292005-05-06 21:37:42 +00002395static int
paul718e3742002-12-13 20:15:29 +00002396ospf_check_sum (struct ospf_header *ospfh)
2397{
2398 u_int32_t ret;
2399 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002400
2401 /* clear auth_data for checksum. */
2402 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2403
2404 /* keep checksum and clear. */
2405 sum = ospfh->checksum;
2406 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2407
2408 /* calculate checksum. */
2409 ret = in_cksum (ospfh, ntohs (ospfh->length));
2410
2411 if (ret != sum)
2412 {
2413 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2414 ret, sum);
2415 return 0;
2416 }
2417
2418 return 1;
2419}
2420
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002421/* Verify, that given link/TOS records are properly sized/aligned and match
2422 Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2423static unsigned
2424ospf_router_lsa_links_examin
2425(
2426 struct router_lsa_link * link,
2427 u_int16_t linkbytes,
2428 const u_int16_t num_links
2429)
2430{
2431 unsigned counted_links = 0, thislinklen;
2432
2433 while (linkbytes)
2434 {
2435 thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
2436 if (thislinklen > linkbytes)
2437 {
2438 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2439 zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
2440 return MSG_NG;
2441 }
2442 link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
2443 linkbytes -= thislinklen;
2444 counted_links++;
2445 }
2446 if (counted_links != num_links)
2447 {
2448 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2449 zlog_debug ("%s: %u link blocks declared, %u present",
2450 __func__, num_links, counted_links);
2451 return MSG_NG;
2452 }
2453 return MSG_OK;
2454}
2455
2456/* Verify, that the given LSA is properly sized/aligned (including type-specific
2457 minimum length constraint). */
2458static unsigned
2459ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
2460{
2461 unsigned ret;
2462 struct router_lsa * rlsa;
2463 if
2464 (
2465 lsah->type < OSPF_MAX_LSA &&
2466 ospf_lsa_minlen[lsah->type] &&
2467 lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
2468 )
2469 {
2470 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2471 zlog_debug ("%s: undersized (%u B) %s",
2472 __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
2473 return MSG_NG;
2474 }
2475 switch (lsah->type)
2476 {
2477 case OSPF_ROUTER_LSA:
2478 /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
2479 if (headeronly)
2480 {
2481 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2482 break;
2483 }
2484 rlsa = (struct router_lsa *) lsah;
2485 ret = ospf_router_lsa_links_examin
2486 (
2487 (struct router_lsa_link *) rlsa->link,
2488 lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
2489 ntohs (rlsa->links) /* 16 bits */
2490 );
2491 break;
2492 case OSPF_AS_EXTERNAL_LSA:
2493 /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
2494 case OSPF_AS_NSSA_LSA:
2495 /* RFC3101 C, idem */
2496 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
2497 break;
2498 /* Following LSA types are considered OK length-wise as soon as their minimum
2499 * length constraint is met and length of the whole LSA is a multiple of 4
2500 * (basic LSA header size is already a multiple of 4). */
2501 case OSPF_NETWORK_LSA:
2502 /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2503 case OSPF_SUMMARY_LSA:
2504 case OSPF_ASBR_SUMMARY_LSA:
2505 /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
2506#ifdef HAVE_OPAQUE_LSA
2507 case OSPF_OPAQUE_LINK_LSA:
2508 case OSPF_OPAQUE_AREA_LSA:
2509 case OSPF_OPAQUE_AS_LSA:
2510 /* RFC5250 A.2, "some number of octets (of application-specific
2511 * data) padded to 32-bit alignment." This is considered equivalent
2512 * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
2513 * file for the detailed analysis of this passage. */
2514#endif
2515 ret = lsalen % 4 ? MSG_NG : MSG_OK;
2516 break;
2517 default:
2518 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2519 zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
2520 return MSG_NG;
2521 }
2522 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2523 zlog_debug ("%s: alignment error in %s",
2524 __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
2525 return ret;
2526}
2527
2528/* Verify if the provided input buffer is a valid sequence of LSAs. This
2529 includes verification of LSA blocks length/alignment and dispatching
2530 of deeper-level checks. */
2531static unsigned
2532ospf_lsaseq_examin
2533(
2534 struct lsa_header *lsah, /* start of buffered data */
2535 size_t length,
2536 const u_char headeronly,
2537 /* When declared_num_lsas is not 0, compare it to the real number of LSAs
2538 and treat the difference as an error. */
2539 const u_int32_t declared_num_lsas
2540)
2541{
2542 u_int32_t counted_lsas = 0;
2543
2544 while (length)
2545 {
2546 u_int16_t lsalen;
2547 if (length < OSPF_LSA_HEADER_SIZE)
2548 {
2549 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2550 zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
2551 __func__, length, counted_lsas);
2552 return MSG_NG;
2553 }
2554 /* save on ntohs() calls here and in the LSA validator */
2555 lsalen = ntohs (lsah->length);
2556 if (lsalen < OSPF_LSA_HEADER_SIZE)
2557 {
2558 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2559 zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
2560 __func__, counted_lsas, lsalen);
2561 return MSG_NG;
2562 }
2563 if (headeronly)
2564 {
2565 /* less checks here and in ospf_lsa_examin() */
2566 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
2567 {
2568 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2569 zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
2570 return MSG_NG;
2571 }
2572 lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
2573 length -= OSPF_LSA_HEADER_SIZE;
2574 }
2575 else
2576 {
2577 /* make sure the input buffer is deep enough before further checks */
2578 if (lsalen > length)
2579 {
2580 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2581 zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2582 __func__, counted_lsas, lsalen, length);
2583 return MSG_NG;
2584 }
2585 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
2586 {
2587 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2588 zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
2589 return MSG_NG;
2590 }
2591 lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
2592 length -= lsalen;
2593 }
2594 counted_lsas++;
2595 }
2596
2597 if (declared_num_lsas && counted_lsas != declared_num_lsas)
2598 {
2599 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2600 zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
2601 __func__, declared_num_lsas, counted_lsas);
2602 return MSG_NG;
2603 }
2604 return MSG_OK;
2605}
2606
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002607/* Verify a complete OSPF packet for proper sizing/alignment. */
2608static unsigned
2609ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2610{
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002611 u_int16_t bytesdeclared, bytesauth;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002612 unsigned ret;
2613 struct ospf_ls_update * lsupd;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002614
2615 /* Length, 1st approximation. */
2616 if (bytesonwire < OSPF_HEADER_SIZE)
2617 {
2618 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2619 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2620 return MSG_NG;
2621 }
2622 /* Now it is safe to access header fields. Performing length check, allow
2623 * for possible extra bytes of crypto auth/padding, which are not counted
2624 * in the OSPF header "length" field. */
Denis Ovsienkoaee56742012-02-28 15:15:29 +04002625 if (oh->version != OSPF_VERSION)
2626 {
2627 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2628 zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
2629 return MSG_NG;
2630 }
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002631 bytesdeclared = ntohs (oh->length);
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002632 if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2633 bytesauth = 0;
2634 else
2635 {
2636 if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE)
2637 {
2638 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2639 zlog_debug ("%s: unsupported crypto auth length (%u B)",
2640 __func__, oh->u.crypt.auth_data_len);
2641 return MSG_NG;
2642 }
2643 bytesauth = OSPF_AUTH_MD5_SIZE;
2644 }
2645 if (bytesdeclared + bytesauth > bytesonwire)
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002646 {
2647 if (IS_DEBUG_OSPF_PACKET (0, RECV))
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002648 zlog_debug ("%s: packet length error (%u real, %u+%u declared)",
2649 __func__, bytesonwire, bytesdeclared, bytesauth);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002650 return MSG_NG;
2651 }
2652 /* Length, 2nd approximation. The type-specific constraint is checked
2653 against declared length, not amount of bytes on wire. */
2654 if
2655 (
2656 oh->type >= OSPF_MSG_HELLO &&
2657 oh->type <= OSPF_MSG_LS_ACK &&
2658 bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2659 )
2660 {
2661 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2662 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2663 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2664 return MSG_NG;
2665 }
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002666 switch (oh->type)
2667 {
2668 case OSPF_MSG_HELLO:
2669 /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
2670 by N>=0 router-IDs. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002671 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002672 break;
2673 case OSPF_MSG_DB_DESC:
2674 /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
2675 by N>=0 header-only LSAs. */
2676 ret = ospf_lsaseq_examin
2677 (
2678 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002679 bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002680 1, /* header-only LSAs */
2681 0
2682 );
2683 break;
2684 case OSPF_MSG_LS_REQ:
2685 /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002686 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002687 OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
2688 break;
2689 case OSPF_MSG_LS_UPD:
2690 /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
2691 by N>=0 full LSAs (with N declared beforehand). */
2692 lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
2693 ret = ospf_lsaseq_examin
2694 (
2695 (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002696 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002697 0, /* full LSAs */
2698 ntohl (lsupd->num_lsas) /* 32 bits */
2699 );
2700 break;
2701 case OSPF_MSG_LS_ACK:
2702 /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
2703 ret = ospf_lsaseq_examin
2704 (
2705 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002706 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002707 1, /* header-only LSAs */
2708 0
2709 );
2710 break;
2711 default:
2712 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2713 zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
2714 return MSG_NG;
2715 }
2716 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2717 zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
2718 return ret;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002719}
2720
paul718e3742002-12-13 20:15:29 +00002721/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002722static int
paul718e3742002-12-13 20:15:29 +00002723ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2724 struct ip *iph, struct ospf_header *ospfh)
2725{
paul718e3742002-12-13 20:15:29 +00002726 /* Check Area ID. */
2727 if (!ospf_check_area_id (oi, ospfh))
2728 {
2729 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2730 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2731 return -1;
2732 }
2733
2734 /* Check network mask, Silently discarded. */
2735 if (! ospf_check_network_mask (oi, iph->ip_src))
2736 {
2737 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2738 IF_NAME (oi), inet_ntoa (iph->ip_src));
2739 return -1;
2740 }
2741
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002742 /* Check authentication. The function handles logging actions, where required. */
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002743 if (! ospf_check_auth (oi, ospfh))
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002744 return -1;
paul718e3742002-12-13 20:15:29 +00002745
2746 return 0;
2747}
2748
2749/* Starting point of packet process function. */
2750int
2751ospf_read (struct thread *thread)
2752{
2753 int ret;
2754 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002755 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002756 struct ospf_interface *oi;
2757 struct ip *iph;
2758 struct ospf_header *ospfh;
2759 u_int16_t length;
2760 struct interface *ifp;
2761
2762 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002763 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002764
2765 /* prepare for next packet. */
2766 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002767
ajs5c333492005-02-23 15:43:01 +00002768 stream_reset(ospf->ibuf);
2769 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002770 return -1;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002771 /* This raw packet is known to be at least as big as its IP header. */
paul718e3742002-12-13 20:15:29 +00002772
ajs5c333492005-02-23 15:43:01 +00002773 /* Note that there should not be alignment problems with this assignment
2774 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002775 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002776 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002777
paulac191232004-10-22 12:05:17 +00002778 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002779 /* Handle cases where the platform does not support retrieving the ifindex,
2780 and also platforms (such as Solaris 8) that claim to support ifindex
2781 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002782 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002783
pauld3f0d622004-05-05 15:27:15 +00002784 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002785 return 0;
paul718e3742002-12-13 20:15:29 +00002786
2787 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002788 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002789 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002790
paul718e3742002-12-13 20:15:29 +00002791 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002792 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002793 {
pauld3241812003-09-29 12:42:39 +00002794 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2795 {
ajs2a42e282004-12-08 18:43:03 +00002796 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002797 inet_ntoa (iph->ip_src));
2798 }
paul718e3742002-12-13 20:15:29 +00002799 return 0;
2800 }
2801
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002802 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2803 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002804 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002805
paul718e3742002-12-13 20:15:29 +00002806 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002807 if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
2808 return -1;
2809 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002810
2811 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002812 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002813
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002814 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2815 after the passive/backbone/other checks below are passed. These checks
2816 in turn access the fields of unverified "ospfh" structure for their own
2817 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002818
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002819 /* If incoming interface is passive one, ignore it. */
2820 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2821 {
2822 char buf[3][INET_ADDRSTRLEN];
2823
2824 if (IS_DEBUG_OSPF_EVENT)
2825 zlog_debug ("ignoring packet from router %s sent to %s, "
2826 "received on a passive interface, %s",
2827 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2828 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2829 inet_ntop(AF_INET, &oi->address->u.prefix4,
2830 buf[2], sizeof(buf[2])));
2831
2832 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2833 {
2834 /* Try to fix multicast membership.
2835 * Some OS:es may have problems in this area,
2836 * make sure it is removed.
2837 */
2838 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2839 ospf_if_set_multicast(oi);
2840 }
2841 return 0;
2842 }
2843
2844
pauld3f0d622004-05-05 15:27:15 +00002845 /* if no local ospf_interface,
2846 * or header area is backbone but ospf_interface is not
2847 * check for VLINK interface
2848 */
2849 if ( (oi == NULL) ||
2850 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2851 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2852 )
2853 {
2854 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2855 {
Paul Jakma88871b12006-06-15 11:41:19 +00002856 if (IS_DEBUG_OSPF_EVENT)
2857 zlog_debug ("Packet from [%s] received on link %s"
2858 " but no ospf_interface",
2859 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002860 return 0;
2861 }
2862 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002863
pauld3f0d622004-05-05 15:27:15 +00002864 /* else it must be a local ospf interface, check it was received on
2865 * correct link
2866 */
2867 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002868 {
Paul Jakma11637432009-08-11 12:25:42 +01002869 if (IS_DEBUG_OSPF_EVENT)
2870 zlog_warn ("Packet from [%s] received on wrong link %s",
2871 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002872 return 0;
2873 }
ajs847947f2005-02-02 18:38:48 +00002874 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002875 {
ajsba6454e2005-02-08 15:37:30 +00002876 char buf[2][INET_ADDRSTRLEN];
2877 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002878 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002879 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2880 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2881 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002882 /* Fix multicast memberships? */
2883 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002884 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002885 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002886 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002887 if (oi->multicast_memberships)
2888 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002889 return 0;
2890 }
paul718e3742002-12-13 20:15:29 +00002891
2892 /*
2893 * If the received packet is destined for AllDRouters, the packet
2894 * should be accepted only if the received ospf interface state is
2895 * either DR or Backup -- endo.
2896 */
2897 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2898 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2899 {
ajsba6454e2005-02-08 15:37:30 +00002900 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002901 inet_ntoa (iph->ip_src), IF_NAME (oi),
2902 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002903 /* Try to fix multicast membership. */
2904 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2905 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002906 return 0;
2907 }
2908
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002909 /* Verify more OSPF header fields. */
2910 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2911 if (ret < 0)
2912 {
2913 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2914 zlog_debug ("ospf_read[%s]: Header check failed, "
2915 "dropping.",
2916 inet_ntoa (iph->ip_src));
2917 return ret;
2918 }
2919
paul718e3742002-12-13 20:15:29 +00002920 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002921 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2922 {
paul718e3742002-12-13 20:15:29 +00002923 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002924 {
ajs2a42e282004-12-08 18:43:03 +00002925 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002926 ospf_packet_dump (ibuf);
2927 }
paul718e3742002-12-13 20:15:29 +00002928
ajs2a42e282004-12-08 18:43:03 +00002929 zlog_debug ("%s received from [%s] via [%s]",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +04002930 LOOKUP (ospf_packet_type_str, ospfh->type),
paul1aa7b392003-04-08 08:51:58 +00002931 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002932 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2933 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002934
2935 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002936 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002937 }
paul718e3742002-12-13 20:15:29 +00002938
paul9985f832005-02-09 15:51:56 +00002939 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002940
2941 /* Adjust size to message length. */
2942 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2943
2944 /* Read rest of the packet and call each sort of packet routine. */
2945 switch (ospfh->type)
2946 {
2947 case OSPF_MSG_HELLO:
2948 ospf_hello (iph, ospfh, ibuf, oi, length);
2949 break;
2950 case OSPF_MSG_DB_DESC:
2951 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2952 break;
2953 case OSPF_MSG_LS_REQ:
2954 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2955 break;
2956 case OSPF_MSG_LS_UPD:
2957 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2958 break;
2959 case OSPF_MSG_LS_ACK:
2960 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2961 break;
2962 default:
2963 zlog (NULL, LOG_WARNING,
2964 "interface %s: OSPF packet header type %d is illegal",
2965 IF_NAME (oi), ospfh->type);
2966 break;
2967 }
2968
paul718e3742002-12-13 20:15:29 +00002969 return 0;
2970}
2971
2972/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002973static void
paul718e3742002-12-13 20:15:29 +00002974ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2975{
2976 struct ospf_header *ospfh;
2977
2978 ospfh = (struct ospf_header *) STREAM_DATA (s);
2979
2980 ospfh->version = (u_char) OSPF_VERSION;
2981 ospfh->type = (u_char) type;
2982
paul68980082003-03-25 05:07:42 +00002983 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002984
2985 ospfh->checksum = 0;
2986 ospfh->area_id = oi->area->area_id;
2987 ospfh->auth_type = htons (ospf_auth_type (oi));
2988
2989 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2990
paul9985f832005-02-09 15:51:56 +00002991 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002992}
2993
2994/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002995static int
paul718e3742002-12-13 20:15:29 +00002996ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2997{
2998 struct crypt_key *ck;
2999
3000 switch (ospf_auth_type (oi))
3001 {
3002 case OSPF_AUTH_NULL:
3003 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
3004 break;
3005 case OSPF_AUTH_SIMPLE:
3006 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
3007 OSPF_AUTH_SIMPLE_SIZE);
3008 break;
3009 case OSPF_AUTH_CRYPTOGRAPHIC:
3010 /* If key is not set, then set 0. */
3011 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
3012 {
3013 ospfh->u.crypt.zero = 0;
3014 ospfh->u.crypt.key_id = 0;
3015 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
3016 }
3017 else
3018 {
paul1eb8ef22005-04-07 07:30:20 +00003019 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00003020 ospfh->u.crypt.zero = 0;
3021 ospfh->u.crypt.key_id = ck->key_id;
3022 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
3023 }
3024 /* note: the seq is done in ospf_make_md5_digest() */
3025 break;
3026 default:
3027 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
3028 break;
3029 }
3030
3031 return 0;
3032}
3033
3034/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00003035static void
paul718e3742002-12-13 20:15:29 +00003036ospf_fill_header (struct ospf_interface *oi,
3037 struct stream *s, u_int16_t length)
3038{
3039 struct ospf_header *ospfh;
3040
3041 ospfh = (struct ospf_header *) STREAM_DATA (s);
3042
3043 /* Fill length. */
3044 ospfh->length = htons (length);
3045
3046 /* Calculate checksum. */
3047 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
3048 ospfh->checksum = in_cksum (ospfh, length);
3049 else
3050 ospfh->checksum = 0;
3051
3052 /* Add Authentication Data. */
3053 ospf_make_auth (oi, ospfh);
3054}
3055
paul4dadc292005-05-06 21:37:42 +00003056static int
paul718e3742002-12-13 20:15:29 +00003057ospf_make_hello (struct ospf_interface *oi, struct stream *s)
3058{
3059 struct ospf_neighbor *nbr;
3060 struct route_node *rn;
3061 u_int16_t length = OSPF_HELLO_MIN_SIZE;
3062 struct in_addr mask;
3063 unsigned long p;
3064 int flag = 0;
3065
3066 /* Set netmask of interface. */
3067 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
3068 oi->type != OSPF_IFTYPE_VIRTUALLINK)
3069 masklen2ip (oi->address->prefixlen, &mask);
3070 else
3071 memset ((char *) &mask, 0, sizeof (struct in_addr));
3072 stream_put_ipv4 (s, mask.s_addr);
3073
3074 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00003075 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
3076 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
3077 else
3078 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00003079
3080 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003081 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00003082 OPTIONS(oi), IF_NAME (oi));
3083
3084 /* Set Options. */
3085 stream_putc (s, OPTIONS (oi));
3086
3087 /* Set Router Priority. */
3088 stream_putc (s, PRIORITY (oi));
3089
3090 /* Set Router Dead Interval. */
3091 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
3092
3093 /* Set Designated Router. */
3094 stream_put_ipv4 (s, DR (oi).s_addr);
3095
paul9985f832005-02-09 15:51:56 +00003096 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003097
3098 /* Set Backup Designated Router. */
3099 stream_put_ipv4 (s, BDR (oi).s_addr);
3100
3101 /* Add neighbor seen. */
3102 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00003103 if ((nbr = rn->info))
3104 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
3105 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
3106 if (nbr->state != NSM_Down) /* This is myself for DR election. */
3107 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003108 {
3109 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00003110 if (nbr->d_router.s_addr != 0
3111 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
3112 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
3113 flag = 1;
paul718e3742002-12-13 20:15:29 +00003114
3115 stream_put_ipv4 (s, nbr->router_id.s_addr);
3116 length += 4;
3117 }
3118
3119 /* Let neighbor generate BackupSeen. */
3120 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00003121 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00003122
3123 return length;
3124}
3125
paul4dadc292005-05-06 21:37:42 +00003126static int
paul718e3742002-12-13 20:15:29 +00003127ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
3128 struct stream *s)
3129{
3130 struct ospf_lsa *lsa;
3131 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
3132 u_char options;
3133 unsigned long pp;
3134 int i;
3135 struct ospf_lsdb *lsdb;
3136
3137 /* Set Interface MTU. */
3138 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3139 stream_putw (s, 0);
3140 else
3141 stream_putw (s, oi->ifp->mtu);
3142
3143 /* Set Options. */
3144 options = OPTIONS (oi);
3145#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003146 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
Lu Feng86ce9512015-01-08 01:39:18 +00003147 SET_FLAG (options, OSPF_OPTION_O);
paul718e3742002-12-13 20:15:29 +00003148#endif /* HAVE_OPAQUE_LSA */
3149 stream_putc (s, options);
3150
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003151 /* DD flags */
paul9985f832005-02-09 15:51:56 +00003152 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003153 stream_putc (s, nbr->dd_flags);
3154
3155 /* Set DD Sequence Number. */
3156 stream_putl (s, nbr->dd_seqnum);
3157
Paul Jakmab5aeb442006-08-30 18:47:37 +00003158 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00003159 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00003160 goto empty;
paul718e3742002-12-13 20:15:29 +00003161
3162 /* Describe LSA Header from Database Summary List. */
3163 lsdb = &nbr->db_sum;
3164
3165 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3166 {
3167 struct route_table *table = lsdb->type[i].db;
3168 struct route_node *rn;
3169
3170 for (rn = route_top (table); rn; rn = route_next (rn))
3171 if ((lsa = rn->info) != NULL)
3172 {
3173#ifdef HAVE_OPAQUE_LSA
3174 if (IS_OPAQUE_LSA (lsa->data->type)
3175 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
3176 {
3177 /* Suppress advertising opaque-informations. */
3178 /* Remove LSA from DB summary list. */
3179 ospf_lsdb_delete (lsdb, lsa);
3180 continue;
3181 }
3182#endif /* HAVE_OPAQUE_LSA */
3183
3184 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
3185 {
3186 struct lsa_header *lsah;
3187 u_int16_t ls_age;
3188
3189 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003190 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003191 break;
3192
3193 /* Keep pointer to LS age. */
3194 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00003195 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003196
3197 /* Proceed stream pointer. */
3198 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3199 length += OSPF_LSA_HEADER_SIZE;
3200
3201 /* Set LS age. */
3202 ls_age = LS_AGE (lsa);
3203 lsah->ls_age = htons (ls_age);
3204
3205 }
3206
3207 /* Remove LSA from DB summary list. */
3208 ospf_lsdb_delete (lsdb, lsa);
3209 }
3210 }
3211
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003212 /* Update 'More' bit */
3213 if (ospf_db_summary_isempty (nbr))
3214 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00003215empty:
3216 if (nbr->state >= NSM_Exchange)
3217 {
3218 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
3219 /* Rewrite DD flags */
3220 stream_putc_at (s, pp, nbr->dd_flags);
3221 }
3222 else
3223 {
3224 assert (IS_SET_DD_M(nbr->dd_flags));
3225 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003226 }
paul718e3742002-12-13 20:15:29 +00003227 return length;
3228}
3229
paul4dadc292005-05-06 21:37:42 +00003230static int
paul718e3742002-12-13 20:15:29 +00003231ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
3232 unsigned long delta, struct ospf_neighbor *nbr,
3233 struct ospf_lsa *lsa)
3234{
3235 struct ospf_interface *oi;
3236
3237 oi = nbr->oi;
3238
3239 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003240 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00003241 return 0;
3242
3243 stream_putl (s, lsa->data->type);
3244 stream_put_ipv4 (s, lsa->data->id.s_addr);
3245 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
3246
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003247 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00003248 nbr->ls_req_last = ospf_lsa_lock (lsa);
3249
3250 *length += 12;
3251 return 1;
3252}
3253
paul4dadc292005-05-06 21:37:42 +00003254static int
paul718e3742002-12-13 20:15:29 +00003255ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
3256{
3257 struct ospf_lsa *lsa;
3258 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003259 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00003260 struct route_table *table;
3261 struct route_node *rn;
3262 int i;
3263 struct ospf_lsdb *lsdb;
3264
3265 lsdb = &nbr->ls_req;
3266
3267 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3268 {
3269 table = lsdb->type[i].db;
3270 for (rn = route_top (table); rn; rn = route_next (rn))
3271 if ((lsa = (rn->info)) != NULL)
3272 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
3273 {
3274 route_unlock_node (rn);
3275 break;
3276 }
3277 }
3278 return length;
3279}
3280
paul4dadc292005-05-06 21:37:42 +00003281static int
paul718e3742002-12-13 20:15:29 +00003282ls_age_increment (struct ospf_lsa *lsa, int delay)
3283{
3284 int age;
3285
3286 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
3287
3288 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3289}
3290
paul4dadc292005-05-06 21:37:42 +00003291static int
hasso52dc7ee2004-09-23 19:18:23 +00003292ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003293{
3294 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00003295 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003296 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00003297 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00003298 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003299 unsigned long pp;
3300 int count = 0;
3301
3302 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003303 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00003304
paul9985f832005-02-09 15:51:56 +00003305 pp = stream_get_endp (s);
3306 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003307 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00003308
gdt86f1fd92005-01-10 14:20:43 +00003309 /* Calculate amount of packet usable for data. */
3310 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3311
paul718e3742002-12-13 20:15:29 +00003312 while ((node = listhead (update)) != NULL)
3313 {
3314 struct lsa_header *lsah;
3315 u_int16_t ls_age;
3316
3317 if (IS_DEBUG_OSPF_EVENT)
Dinesh G Dutt1c063342014-09-30 13:04:45 -07003318 zlog_debug ("ospf_make_ls_upd: List Iteration %d", count);
paul718e3742002-12-13 20:15:29 +00003319
paul1eb8ef22005-04-07 07:30:20 +00003320 lsa = listgetdata (node);
3321
paul718e3742002-12-13 20:15:29 +00003322 assert (lsa->data);
3323
paul68b73392004-09-12 14:21:37 +00003324 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00003325 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00003326 break;
3327
paul718e3742002-12-13 20:15:29 +00003328 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00003329 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003330
3331 /* Put LSA to Link State Request. */
3332 stream_put (s, lsa->data, ntohs (lsa->data->length));
3333
3334 /* Set LS age. */
3335 /* each hop must increment an lsa_age by transmit_delay
3336 of OSPF interface */
3337 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3338 lsah->ls_age = htons (ls_age);
3339
3340 length += ntohs (lsa->data->length);
3341 count++;
3342
3343 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003344 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003345 }
3346
3347 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003348 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003349
3350 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003351 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003352 return length;
3353}
3354
paul4dadc292005-05-06 21:37:42 +00003355static int
hasso52dc7ee2004-09-23 19:18:23 +00003356ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003357{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003358 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003359 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003360 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003361 struct ospf_lsa *lsa;
3362
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003363 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003364 {
paul718e3742002-12-13 20:15:29 +00003365 assert (lsa);
3366
gdt86f1fd92005-01-10 14:20:43 +00003367 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003368 break;
3369
3370 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3371 length += OSPF_LSA_HEADER_SIZE;
3372
paul718e3742002-12-13 20:15:29 +00003373 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003374 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003375 }
3376
paul718e3742002-12-13 20:15:29 +00003377 return length;
3378}
3379
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003380static void
3381ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003382{
3383 struct ospf_packet *op;
3384 u_int16_t length = OSPF_HEADER_SIZE;
3385
3386 op = ospf_packet_new (oi->ifp->mtu);
3387
3388 /* Prepare OSPF common header. */
3389 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3390
3391 /* Prepare OSPF Hello body. */
3392 length += ospf_make_hello (oi, op->s);
3393
3394 /* Fill OSPF header. */
3395 ospf_fill_header (oi, op->s, length);
3396
3397 /* Set packet length. */
3398 op->length = length;
3399
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003400 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003401
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003402 /* Add packet to the top of the interface output queue, so that they
3403 * can't get delayed by things like long queues of LS Update packets
3404 */
3405 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003406
3407 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003408 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003409}
3410
paul4dadc292005-05-06 21:37:42 +00003411static void
paul718e3742002-12-13 20:15:29 +00003412ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3413{
3414 struct ospf_interface *oi;
3415
3416 oi = nbr_nbma->oi;
3417 assert(oi);
3418
3419 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003420 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003421 return;
3422
3423 if (oi->type != OSPF_IFTYPE_NBMA)
3424 return;
3425
3426 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3427 return;
3428
3429 if (PRIORITY(oi) == 0)
3430 return;
3431
3432 if (nbr_nbma->priority == 0
3433 && oi->state != ISM_DR && oi->state != ISM_Backup)
3434 return;
3435
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003436 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003437}
3438
3439int
3440ospf_poll_timer (struct thread *thread)
3441{
3442 struct ospf_nbr_nbma *nbr_nbma;
3443
3444 nbr_nbma = THREAD_ARG (thread);
3445 nbr_nbma->t_poll = NULL;
3446
3447 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003448 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003449 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3450
3451 ospf_poll_send (nbr_nbma);
3452
3453 if (nbr_nbma->v_poll > 0)
3454 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3455 nbr_nbma->v_poll);
3456
3457 return 0;
3458}
3459
3460
3461int
3462ospf_hello_reply_timer (struct thread *thread)
3463{
3464 struct ospf_neighbor *nbr;
3465
3466 nbr = THREAD_ARG (thread);
3467 nbr->t_hello_reply = NULL;
3468
3469 assert (nbr->oi);
3470
3471 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003472 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003473 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3474
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003475 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003476
3477 return 0;
3478}
3479
3480/* Send OSPF Hello. */
3481void
3482ospf_hello_send (struct ospf_interface *oi)
3483{
paul718e3742002-12-13 20:15:29 +00003484 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003485 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003486 return;
3487
paul718e3742002-12-13 20:15:29 +00003488 if (oi->type == OSPF_IFTYPE_NBMA)
3489 {
3490 struct ospf_neighbor *nbr;
3491 struct route_node *rn;
3492
3493 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3494 if ((nbr = rn->info))
3495 if (nbr != oi->nbr_self)
3496 if (nbr->state != NSM_Down)
3497 {
3498 /* RFC 2328 Section 9.5.1
3499 If the router is not eligible to become Designated Router,
3500 it must periodically send Hello Packets to both the
3501 Designated Router and the Backup Designated Router (if they
3502 exist). */
3503 if (PRIORITY(oi) == 0 &&
3504 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3505 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3506 continue;
3507
3508 /* If the router is eligible to become Designated Router, it
3509 must periodically send Hello Packets to all neighbors that
3510 are also eligible. In addition, if the router is itself the
3511 Designated Router or Backup Designated Router, it must also
3512 send periodic Hello Packets to all other neighbors. */
3513
3514 if (nbr->priority == 0 && oi->state == ISM_DROther)
3515 continue;
3516 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003517 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003518 }
paul718e3742002-12-13 20:15:29 +00003519 }
3520 else
3521 {
3522 /* Decide destination address. */
3523 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003524 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3525 else
3526 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003527 }
3528}
3529
3530/* Send OSPF Database Description. */
3531void
3532ospf_db_desc_send (struct ospf_neighbor *nbr)
3533{
3534 struct ospf_interface *oi;
3535 struct ospf_packet *op;
3536 u_int16_t length = OSPF_HEADER_SIZE;
3537
3538 oi = nbr->oi;
3539 op = ospf_packet_new (oi->ifp->mtu);
3540
3541 /* Prepare OSPF common header. */
3542 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3543
3544 /* Prepare OSPF Database Description body. */
3545 length += ospf_make_db_desc (oi, nbr, op->s);
3546
3547 /* Fill OSPF header. */
3548 ospf_fill_header (oi, op->s, length);
3549
3550 /* Set packet length. */
3551 op->length = length;
3552
3553 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003554 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3555 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3556 else
3557 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003558
3559 /* Add packet to the interface output queue. */
3560 ospf_packet_add (oi, op);
3561
3562 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003563 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003564
3565 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3566 if (nbr->last_send)
3567 ospf_packet_free (nbr->last_send);
3568 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003569 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003570}
3571
3572/* Re-send Database Description. */
3573void
3574ospf_db_desc_resend (struct ospf_neighbor *nbr)
3575{
3576 struct ospf_interface *oi;
3577
3578 oi = nbr->oi;
3579
3580 /* Add packet to the interface output queue. */
3581 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3582
3583 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003584 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003585}
3586
3587/* Send Link State Request. */
3588void
3589ospf_ls_req_send (struct ospf_neighbor *nbr)
3590{
3591 struct ospf_interface *oi;
3592 struct ospf_packet *op;
3593 u_int16_t length = OSPF_HEADER_SIZE;
3594
3595 oi = nbr->oi;
3596 op = ospf_packet_new (oi->ifp->mtu);
3597
3598 /* Prepare OSPF common header. */
3599 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3600
3601 /* Prepare OSPF Link State Request body. */
3602 length += ospf_make_ls_req (nbr, op->s);
3603 if (length == OSPF_HEADER_SIZE)
3604 {
3605 ospf_packet_free (op);
3606 return;
3607 }
3608
3609 /* Fill OSPF header. */
3610 ospf_fill_header (oi, op->s, length);
3611
3612 /* Set packet length. */
3613 op->length = length;
3614
3615 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003616 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3617 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3618 else
3619 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003620
3621 /* Add packet to the interface output queue. */
3622 ospf_packet_add (oi, op);
3623
3624 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003625 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003626
3627 /* Add Link State Request Retransmission Timer. */
3628 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3629}
3630
3631/* Send Link State Update with an LSA. */
3632void
3633ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3634 int flag)
3635{
hasso52dc7ee2004-09-23 19:18:23 +00003636 struct list *update;
paul718e3742002-12-13 20:15:29 +00003637
3638 update = list_new ();
3639
3640 listnode_add (update, lsa);
3641 ospf_ls_upd_send (nbr, update, flag);
3642
3643 list_delete (update);
3644}
3645
paul68b73392004-09-12 14:21:37 +00003646/* Determine size for packet. Must be at least big enough to accomodate next
3647 * LSA on list, which may be bigger than MTU size.
3648 *
3649 * Return pointer to new ospf_packet
3650 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3651 * on packet sizes (in which case offending LSA is deleted from update list)
3652 */
3653static struct ospf_packet *
3654ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3655{
3656 struct ospf_lsa *lsa;
3657 struct listnode *ln;
3658 size_t size;
3659 static char warned = 0;
3660
paul1eb8ef22005-04-07 07:30:20 +00003661 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003662 assert (lsa->data);
3663
3664 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3665 > ospf_packet_max (oi))
3666 {
3667 if (!warned)
3668 {
3669 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3670 "will need to fragment. Not optimal. Try divide up"
3671 " your network with areas. Use 'debug ospf packet send'"
3672 " to see details, or look at 'show ip ospf database ..'");
3673 warned = 1;
3674 }
3675
3676 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003677 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003678 " %d bytes originated by %s, will be fragmented!",
3679 inet_ntoa (lsa->data->id),
3680 ntohs (lsa->data->length),
3681 inet_ntoa (lsa->data->adv_router));
3682
3683 /*
3684 * Allocate just enough to fit this LSA only, to avoid including other
3685 * LSAs in fragmented LSA Updates.
3686 */
3687 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3688 + OSPF_LS_UPD_MIN_SIZE;
3689 }
3690 else
3691 size = oi->ifp->mtu;
3692
3693 if (size > OSPF_MAX_PACKET_SIZE)
3694 {
3695 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003696 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003697 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003698 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003699 (long int) size);
paul68b73392004-09-12 14:21:37 +00003700 list_delete_node (update, ln);
3701 return NULL;
3702 }
3703
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003704 /* IP header is built up separately by ospf_write(). This means, that we must
3705 * reduce the "affordable" size just calculated by length of an IP header.
3706 * This makes sure, that even if we manage to fill the payload with LSA data
3707 * completely, the final packet (our data plus IP header) still fits into
3708 * outgoing interface MTU. This correction isn't really meaningful for an
3709 * oversized LSA, but for consistency the correction is done for both cases.
3710 *
3711 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3712 */
3713 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003714}
3715
paul718e3742002-12-13 20:15:29 +00003716static void
hasso52dc7ee2004-09-23 19:18:23 +00003717ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003718 struct in_addr addr)
3719{
3720 struct ospf_packet *op;
3721 u_int16_t length = OSPF_HEADER_SIZE;
3722
3723 if (IS_DEBUG_OSPF_EVENT)
Dinesh G Dutt1c063342014-09-30 13:04:45 -07003724 zlog_debug ("listcount = %d, [%s]dst %s", listcount (update), IF_NAME(oi),
3725 inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003726
3727 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003728
3729 /* Prepare OSPF common header. */
3730 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3731
paul59ea14c2004-07-14 20:50:36 +00003732 /* Prepare OSPF Link State Update body.
3733 * Includes Type-7 translation.
3734 */
paul718e3742002-12-13 20:15:29 +00003735 length += ospf_make_ls_upd (oi, update, op->s);
3736
3737 /* Fill OSPF header. */
3738 ospf_fill_header (oi, op->s, length);
3739
3740 /* Set packet length. */
3741 op->length = length;
3742
3743 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003744 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3745 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3746 else
3747 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003748
3749 /* Add packet to the interface output queue. */
3750 ospf_packet_add (oi, op);
3751
3752 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003753 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003754}
3755
3756static int
3757ospf_ls_upd_send_queue_event (struct thread *thread)
3758{
3759 struct ospf_interface *oi = THREAD_ARG(thread);
3760 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003761 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003762 struct list *update;
paul68b73392004-09-12 14:21:37 +00003763 char again = 0;
paul718e3742002-12-13 20:15:29 +00003764
3765 oi->t_ls_upd_event = NULL;
3766
3767 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003768 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003769
paul736d3442003-07-24 23:22:57 +00003770 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003771 {
paul736d3442003-07-24 23:22:57 +00003772 rnext = route_next (rn);
3773
paul718e3742002-12-13 20:15:29 +00003774 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003775 continue;
paul68b73392004-09-12 14:21:37 +00003776
3777 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003778
paul48fe13b2004-07-27 17:40:44 +00003779 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003780
paul68b73392004-09-12 14:21:37 +00003781 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003782 if (listcount(update) == 0)
3783 {
3784 list_delete (rn->info);
3785 rn->info = NULL;
3786 route_unlock_node (rn);
3787 }
3788 else
paul68b73392004-09-12 14:21:37 +00003789 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003790 }
3791
3792 if (again != 0)
3793 {
3794 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003795 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003796 " %d nodes to try again, raising new event", again);
3797 oi->t_ls_upd_event =
3798 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003799 }
3800
3801 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003802 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003803
paul718e3742002-12-13 20:15:29 +00003804 return 0;
3805}
3806
3807void
hasso52dc7ee2004-09-23 19:18:23 +00003808ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003809{
3810 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003811 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003812 struct prefix_ipv4 p;
3813 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003814 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003815
3816 oi = nbr->oi;
3817
3818 p.family = AF_INET;
3819 p.prefixlen = IPV4_MAX_BITLEN;
3820
3821 /* Decide destination address. */
3822 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3823 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003824 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3825 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003826 else if (flag == OSPF_SEND_PACKET_DIRECT)
3827 p.prefix = nbr->address.u.prefix4;
3828 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3829 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003830 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3831 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003832 else
3833 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3834
3835 if (oi->type == OSPF_IFTYPE_NBMA)
3836 {
3837 if (flag == OSPF_SEND_PACKET_INDIRECT)
3838 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3839 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3840 zlog_warn ("* LS-Update is sent to myself.");
3841 }
3842
3843 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3844
3845 if (rn->info == NULL)
3846 rn->info = list_new ();
3847
paul1eb8ef22005-04-07 07:30:20 +00003848 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003849 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003850
3851 if (oi->t_ls_upd_event == NULL)
3852 oi->t_ls_upd_event =
3853 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3854}
3855
3856static void
hasso52dc7ee2004-09-23 19:18:23 +00003857ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3858 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003859{
3860 struct ospf_packet *op;
3861 u_int16_t length = OSPF_HEADER_SIZE;
3862
3863 op = ospf_packet_new (oi->ifp->mtu);
3864
3865 /* Prepare OSPF common header. */
3866 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3867
3868 /* Prepare OSPF Link State Acknowledgment body. */
3869 length += ospf_make_ls_ack (oi, ack, op->s);
3870
3871 /* Fill OSPF header. */
3872 ospf_fill_header (oi, op->s, length);
3873
3874 /* Set packet length. */
3875 op->length = length;
3876
3877 /* Set destination IP address. */
3878 op->dst = dst;
3879
3880 /* Add packet to the interface output queue. */
3881 ospf_packet_add (oi, op);
3882
3883 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003884 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003885}
3886
3887static int
3888ospf_ls_ack_send_event (struct thread *thread)
3889{
3890 struct ospf_interface *oi = THREAD_ARG (thread);
3891
3892 oi->t_ls_ack_direct = NULL;
3893
3894 while (listcount (oi->ls_ack_direct.ls_ack))
3895 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3896 oi->ls_ack_direct.dst);
3897
3898 return 0;
3899}
3900
3901void
3902ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3903{
3904 struct ospf_interface *oi = nbr->oi;
3905
3906 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3907 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3908
3909 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3910
3911 if (oi->t_ls_ack_direct == NULL)
3912 oi->t_ls_ack_direct =
3913 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3914}
3915
3916/* Send Link State Acknowledgment delayed. */
3917void
3918ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3919{
3920 struct in_addr dst;
3921
3922 /* Decide destination address. */
3923 /* RFC2328 Section 13.5 On non-broadcast
3924 networks, delayed Link State Acknowledgment packets must be
3925 unicast separately over each adjacency (i.e., neighbor whose
3926 state is >= Exchange). */
3927 if (oi->type == OSPF_IFTYPE_NBMA)
3928 {
3929 struct ospf_neighbor *nbr;
3930 struct route_node *rn;
3931
3932 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3933 if ((nbr = rn->info) != NULL)
3934 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3935 while (listcount (oi->ls_ack))
3936 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3937 return;
3938 }
3939 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3940 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3941 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3942 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3943 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3944 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003945 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3946 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003947 else
3948 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3949
3950 while (listcount (oi->ls_ack))
3951 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3952}