blob: facba89509de0998ed4a04801a7d9e37ca76bfaa [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;
paul6a99f832004-09-27 12:56:30 +0000647 u_int16_t maxdatasize;
David Lamparterce93c342015-09-15 02:11:45 -0700648#endif /* WANT_OSPF_WRITE_FRAGMENT */
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
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000663 /* convenience - max OSPF data per packet,
664 * and reliability - not more data, than our
665 * socket can accept
666 */
667 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
668 sizeof (struct ip);
David Lamparterce93c342015-09-15 02:11:45 -0700669#endif /* WANT_OSPF_WRITE_FRAGMENT */
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
Olivier Dugeon29a14012016-04-19 18:42:40 +0200885 if (CHECK_FLAG (hello->options, OSPF_OPTION_MT))
paul718e3742002-12-13 20:15:29 +0000886 {
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
paul68980082003-03-25 05:07:42 +0000897 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000898 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
899 {
900 /*
901 * This router does know the correct usage of O-bit
902 * the bit should be set in DD packet only.
903 */
904 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
905 inet_ntoa (ospfh->router_id));
906#ifdef STRICT_OBIT_USAGE_CHECK
907 return; /* Reject this packet. */
908#else /* STRICT_OBIT_USAGE_CHECK */
909 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
910#endif /* STRICT_OBIT_USAGE_CHECK */
911 }
paul718e3742002-12-13 20:15:29 +0000912
913 /* new for NSSA is to ensure that NP is on and E is off */
914
paul718e3742002-12-13 20:15:29 +0000915 if (oi->area->external_routing == OSPF_AREA_NSSA)
916 {
917 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
918 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
919 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
920 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
921 {
922 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
923 return;
924 }
925 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000926 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000927 }
928 else
paul718e3742002-12-13 20:15:29 +0000929 /* The setting of the E-bit found in the Hello Packet's Options
930 field must match this area's ExternalRoutingCapability A
931 mismatch causes processing to stop and the packet to be
932 dropped. The setting of the rest of the bits in the Hello
933 Packet's Options field should be ignored. */
934 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
935 CHECK_FLAG (hello->options, OSPF_OPTION_E))
936 {
ajs3aa8d5f2004-12-11 18:00:06 +0000937 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
938 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000939 return;
940 }
paul718e3742002-12-13 20:15:29 +0000941
pauld3f0d622004-05-05 15:27:15 +0000942 /* get neighbour struct */
943 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
944
945 /* neighbour must be valid, ospf_nbr_get creates if none existed */
946 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000947
948 old_state = nbr->state;
949
950 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000951 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000952
953 /* RFC2328 Section 9.5.1
954 If the router is not eligible to become Designated Router,
955 (snip) It must also send an Hello Packet in reply to an
956 Hello Packet received from any eligible neighbor (other than
957 the current Designated Router and Backup Designated Router). */
958 if (oi->type == OSPF_IFTYPE_NBMA)
959 if (PRIORITY(oi) == 0 && hello->priority > 0
960 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
961 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
962 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
963 OSPF_HELLO_REPLY_DELAY);
964
965 /* on NBMA network type, it happens to receive bidirectional Hello packet
966 without advance 1-Way Received event.
967 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
968 if (oi->type == OSPF_IFTYPE_NBMA &&
969 (old_state == NSM_Down || old_state == NSM_Attempt))
970 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000971 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000972 nbr->priority = hello->priority;
973 nbr->d_router = hello->d_router;
974 nbr->bd_router = hello->bd_router;
975 return;
976 }
977
paul68980082003-03-25 05:07:42 +0000978 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000979 size - OSPF_HELLO_MIN_SIZE))
980 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000981 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000982 nbr->options |= hello->options;
983 }
984 else
985 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000986 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000987 /* Set neighbor information. */
988 nbr->priority = hello->priority;
989 nbr->d_router = hello->d_router;
990 nbr->bd_router = hello->bd_router;
991 return;
992 }
993
994 /* If neighbor itself declares DR and no BDR exists,
995 cause event BackupSeen */
996 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
997 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
998 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
999
1000 /* neighbor itself declares BDR. */
1001 if (oi->state == ISM_Waiting &&
1002 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
1003 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
1004
1005 /* had not previously. */
1006 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
1007 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
1008 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
1009 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
1010 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1011
1012 /* had not previously. */
1013 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
1014 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
1015 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
1016 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
1017 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1018
1019 /* Neighbor priority check. */
1020 if (nbr->priority >= 0 && nbr->priority != hello->priority)
1021 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1022
1023 /* Set neighbor information. */
1024 nbr->priority = hello->priority;
1025 nbr->d_router = hello->d_router;
1026 nbr->bd_router = hello->bd_router;
1027}
1028
1029/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +00001030static void
paul718e3742002-12-13 20:15:29 +00001031ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1032 struct ospf_db_desc *dd)
1033{
1034 nbr->last_recv.flags = dd->flags;
1035 nbr->last_recv.options = dd->options;
1036 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1037}
1038
1039/* Process rest of DD packet. */
1040static void
1041ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1042 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1043 u_int16_t size)
1044{
1045 struct ospf_lsa *new, *find;
1046 struct lsa_header *lsah;
1047
paul9985f832005-02-09 15:51:56 +00001048 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001049 for (size -= OSPF_DB_DESC_MIN_SIZE;
1050 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1051 {
1052 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001053 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001054
1055 /* Unknown LS type. */
1056 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1057 {
ajsbec595a2004-11-30 22:38:43 +00001058 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001059 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1060 return;
1061 }
1062
paul718e3742002-12-13 20:15:29 +00001063 if (IS_OPAQUE_LSA (lsah->type)
1064 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1065 {
1066 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1067 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1068 return;
1069 }
paul718e3742002-12-13 20:15:29 +00001070
1071 switch (lsah->type)
1072 {
1073 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00001074 case OSPF_OPAQUE_AS_LSA:
paul718e3742002-12-13 20:15:29 +00001075 /* Check for stub area. Reject if AS-External from stub but
1076 allow if from NSSA. */
1077 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001078 {
1079 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1080 lsah->type, inet_ntoa (lsah->id),
1081 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1082 "STUB" : "NSSA");
1083 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1084 return;
1085 }
1086 break;
1087 default:
1088 break;
1089 }
1090
1091 /* Create LS-request object. */
1092 new = ospf_ls_request_new (lsah);
1093
1094 /* Lookup received LSA, then add LS request list. */
1095 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001096
1097 /* ospf_lsa_more_recent is fine with NULL pointers */
1098 switch (ospf_lsa_more_recent (find, new))
1099 {
1100 case -1:
1101 /* Neighbour has a more recent LSA, we must request it */
1102 ospf_ls_request_add (nbr, new);
1103 case 0:
1104 /* If we have a copy of this LSA, it's either less recent
1105 * and we're requesting it from neighbour (the case above), or
1106 * it's as recent and we both have same copy (this case).
1107 *
1108 * In neither of these two cases is there any point in
1109 * describing our copy of the LSA to the neighbour in a
1110 * DB-Summary packet, if we're still intending to do so.
1111 *
1112 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1113 * backward compatible optimisation to OSPF DB Exchange /
1114 * DB Description process implemented here.
1115 */
1116 if (find)
1117 ospf_lsdb_delete (&nbr->db_sum, find);
1118 ospf_lsa_discard (new);
1119 break;
1120 default:
1121 /* We have the more recent copy, nothing specific to do:
1122 * - no need to request neighbours stale copy
1123 * - must leave DB summary list copy alone
1124 */
1125 if (IS_DEBUG_OSPF_EVENT)
1126 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1127 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1128 ospf_lsa_discard (new);
1129 }
paul718e3742002-12-13 20:15:29 +00001130 }
1131
1132 /* Master */
1133 if (IS_SET_DD_MS (nbr->dd_flags))
1134 {
1135 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001136
1137 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001138 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1139 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1140 else
paul718e3742002-12-13 20:15:29 +00001141 ospf_db_desc_send (nbr);
1142 }
1143 /* Slave */
1144 else
1145 {
1146 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1147
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001148 /* Send DD packet in reply.
1149 *
1150 * Must be done to acknowledge the Master's DD, regardless of
1151 * whether we have more LSAs ourselves to describe.
1152 *
1153 * This function will clear the 'More' bit, if after this DD
1154 * we have no more LSAs to describe to the master..
1155 */
paul718e3742002-12-13 20:15:29 +00001156 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001157
1158 /* Slave can raise ExchangeDone now, if master is also done */
1159 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1160 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001161 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001162
paul718e3742002-12-13 20:15:29 +00001163 /* Save received neighbor values from DD. */
1164 ospf_db_desc_save_current (nbr, dd);
1165}
1166
paul4dadc292005-05-06 21:37:42 +00001167static int
paul718e3742002-12-13 20:15:29 +00001168ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1169{
1170 /* Is DD duplicated? */
1171 if (dd->options == nbr->last_recv.options &&
1172 dd->flags == nbr->last_recv.flags &&
1173 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1174 return 1;
1175
1176 return 0;
1177}
1178
1179/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001180static void
paul718e3742002-12-13 20:15:29 +00001181ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1182 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1183{
1184 struct ospf_db_desc *dd;
1185 struct ospf_neighbor *nbr;
1186
1187 /* Increment statistics. */
1188 oi->db_desc_in++;
1189
1190 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001191
pauld3f0d622004-05-05 15:27:15 +00001192 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001193 if (nbr == NULL)
1194 {
1195 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1196 inet_ntoa (ospfh->router_id));
1197 return;
1198 }
1199
1200 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001201 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1202 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001203 {
ajs3aa8d5f2004-12-11 18:00:06 +00001204 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1205 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1206 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001207 return;
1208 }
1209
pauld363df22003-06-19 00:26:34 +00001210 /*
1211 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1212 * required. In fact at least JunOS sends DD packets with P bit clear.
1213 * Until proper solution is developped, this hack should help.
1214 *
1215 * Update: According to the RFCs, N bit is specified /only/ for Hello
1216 * options, unfortunately its use in DD options is not specified. Hence some
1217 * implementations follow E-bit semantics and set it in DD options, and some
1218 * treat it as unspecified and hence follow the directive "default for
1219 * options is clear", ie unset.
1220 *
1221 * Reset the flag, as ospfd follows E-bit semantics.
1222 */
1223 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1224 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1225 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1226 {
1227 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001228 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001229 inet_ntoa (nbr->router_id) );
1230 SET_FLAG (dd->options, OSPF_OPTION_NP);
1231 }
pauld363df22003-06-19 00:26:34 +00001232
paul718e3742002-12-13 20:15:29 +00001233#ifdef REJECT_IF_TBIT_ON
Olivier Dugeon29a14012016-04-19 18:42:40 +02001234 if (CHECK_FLAG (dd->options, OSPF_OPTION_MT))
paul718e3742002-12-13 20:15:29 +00001235 {
1236 /*
1237 * In Hello protocol, optional capability must have checked
1238 * to prevent this T-bit enabled router be my neighbor.
1239 */
1240 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1241 return;
1242 }
1243#endif /* REJECT_IF_TBIT_ON */
1244
paul718e3742002-12-13 20:15:29 +00001245 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001246 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001247 {
1248 /*
1249 * This node is not configured to handle O-bit, for now.
1250 * Clear it to ignore unsupported capability proposed by neighbor.
1251 */
1252 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1253 }
paul718e3742002-12-13 20:15:29 +00001254
Paul Jakma57c5c652010-01-07 06:12:53 +00001255 /* Add event to thread. */
1256 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1257
paul718e3742002-12-13 20:15:29 +00001258 /* Process DD packet by neighbor status. */
1259 switch (nbr->state)
1260 {
1261 case NSM_Down:
1262 case NSM_Attempt:
1263 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001264 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001265 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001266 LOOKUP (ospf_nsm_state_msg, nbr->state));
1267 break;
1268 case NSM_Init:
1269 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1270 /* If the new state is ExStart, the processing of the current
1271 packet should then continue in this new state by falling
1272 through to case ExStart below. */
1273 if (nbr->state != NSM_ExStart)
1274 break;
1275 case NSM_ExStart:
1276 /* Initial DBD */
1277 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1278 (size == OSPF_DB_DESC_MIN_SIZE))
1279 {
paul68980082003-03-25 05:07:42 +00001280 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001281 {
1282 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001283 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001284 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001285 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001286
1287 /* Reset I/MS */
1288 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001289 }
1290 else
1291 {
1292 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001293 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001294 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001295 break;
1296 }
1297 }
1298 /* Ack from the Slave */
1299 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1300 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001301 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001302 {
ajs17eaa722004-12-29 21:04:48 +00001303 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001304 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001305 /* Reset I, leaving MS */
1306 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001307 }
1308 else
1309 {
ajs3aa8d5f2004-12-11 18:00:06 +00001310 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1311 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001312 break;
1313 }
1314
1315 /* This is where the real Options are saved */
1316 nbr->options = dd->options;
1317
paul68980082003-03-25 05:07:42 +00001318 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001319 {
1320 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001321 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001322 inet_ntoa (nbr->router_id),
1323 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1324
1325 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1326 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1327 {
paul6d452762005-11-03 11:15:44 +00001328 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1329 "Opaque-LSAs cannot be reliably advertised "
1330 "in this network.",
1331 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001332 /* This situation is undesirable, but not a real error. */
1333 }
1334 }
paul718e3742002-12-13 20:15:29 +00001335
1336 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1337
1338 /* continue processing rest of packet. */
1339 ospf_db_desc_proc (s, oi, nbr, dd, size);
1340 break;
1341 case NSM_Exchange:
1342 if (ospf_db_desc_is_dup (dd, nbr))
1343 {
1344 if (IS_SET_DD_MS (nbr->dd_flags))
1345 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001346 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001347 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001348 else
1349 /* Slave: cause to retransmit the last Database Description. */
1350 {
paul6d452762005-11-03 11:15:44 +00001351 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001352 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001353 ospf_db_desc_resend (nbr);
1354 }
1355 break;
1356 }
1357
1358 /* Otherwise DD packet should be checked. */
1359 /* Check Master/Slave bit mismatch */
1360 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1361 {
ajs3aa8d5f2004-12-11 18:00:06 +00001362 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1363 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001364 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1365 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001366 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001367 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001368 break;
1369 }
1370
1371 /* Check initialize bit is set. */
1372 if (IS_SET_DD_I (dd->flags))
1373 {
paul6d452762005-11-03 11:15:44 +00001374 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001375 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001376 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1377 break;
1378 }
1379
1380 /* Check DD Options. */
1381 if (dd->options != nbr->options)
1382 {
1383#ifdef ORIGINAL_CODING
1384 /* Save the new options for debugging */
1385 nbr->options = dd->options;
1386#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001387 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1388 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001389 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1390 break;
1391 }
1392
1393 /* Check DD sequence number. */
1394 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1395 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1396 (!IS_SET_DD_MS (nbr->dd_flags) &&
1397 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1398 {
ajs3aa8d5f2004-12-11 18:00:06 +00001399 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1400 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001401 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1402 break;
1403 }
1404
1405 /* Continue processing rest of packet. */
1406 ospf_db_desc_proc (s, oi, nbr, dd, size);
1407 break;
1408 case NSM_Loading:
1409 case NSM_Full:
1410 if (ospf_db_desc_is_dup (dd, nbr))
1411 {
1412 if (IS_SET_DD_MS (nbr->dd_flags))
1413 {
1414 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001415 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1416 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001417 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001418 break;
1419 }
1420 else
1421 {
1422 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001423 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001424 t = tv_sub (now, nbr->last_send_ts);
1425 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1426 {
1427 /* In states Loading and Full the slave must resend
1428 its last Database Description packet in response to
1429 duplicate Database Description packets received
1430 from the master. For this reason the slave must
1431 wait RouterDeadInterval seconds before freeing the
1432 last Database Description packet. Reception of a
1433 Database Description packet from the master after
1434 this interval will generate a SeqNumberMismatch
1435 neighbor event. RFC2328 Section 10.8 */
1436 ospf_db_desc_resend (nbr);
1437 break;
1438 }
1439 }
1440 }
1441
1442 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1443 break;
1444 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001445 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1446 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001447 break;
1448 }
1449}
1450
1451#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1452
1453/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001454static void
paul718e3742002-12-13 20:15:29 +00001455ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1456 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1457{
1458 struct ospf_neighbor *nbr;
1459 u_int32_t ls_type;
1460 struct in_addr ls_id;
1461 struct in_addr adv_router;
1462 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001463 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001464 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001465
1466 /* Increment statistics. */
1467 oi->ls_req_in++;
1468
pauld3f0d622004-05-05 15:27:15 +00001469 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001470 if (nbr == NULL)
1471 {
1472 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1473 inet_ntoa (ospfh->router_id));
1474 return;
1475 }
1476
Paul Jakma57c5c652010-01-07 06:12:53 +00001477 /* Add event to thread. */
1478 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1479
paul718e3742002-12-13 20:15:29 +00001480 /* Neighbor State should be Exchange or later. */
1481 if (nbr->state != NSM_Exchange &&
1482 nbr->state != NSM_Loading &&
1483 nbr->state != NSM_Full)
1484 {
ajsbec595a2004-11-30 22:38:43 +00001485 zlog_warn ("Link State Request received from %s: "
1486 "Neighbor state is %s, packet discarded.",
1487 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001488 LOOKUP (ospf_nsm_state_msg, nbr->state));
1489 return;
1490 }
1491
1492 /* Send Link State Update for ALL requested LSAs. */
1493 ls_upd = list_new ();
1494 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1495
1496 while (size >= OSPF_LSA_KEY_SIZE)
1497 {
1498 /* Get one slice of Link State Request. */
1499 ls_type = stream_getl (s);
1500 ls_id.s_addr = stream_get_ipv4 (s);
1501 adv_router.s_addr = stream_get_ipv4 (s);
1502
1503 /* Verify LSA type. */
1504 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1505 {
1506 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1507 list_delete (ls_upd);
1508 return;
1509 }
1510
1511 /* Search proper LSA in LSDB. */
1512 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1513 if (find == NULL)
1514 {
1515 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1516 list_delete (ls_upd);
1517 return;
1518 }
1519
gdt86f1fd92005-01-10 14:20:43 +00001520 /* Packet overflows MTU size, send immediately. */
1521 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001522 {
1523 if (oi->type == OSPF_IFTYPE_NBMA)
1524 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1525 else
1526 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1527
1528 /* Only remove list contents. Keep ls_upd. */
1529 list_delete_all_node (ls_upd);
1530
1531 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1532 }
1533
1534 /* Append LSA to update list. */
1535 listnode_add (ls_upd, find);
1536 length += ntohs (find->data->length);
1537
1538 size -= OSPF_LSA_KEY_SIZE;
1539 }
1540
1541 /* Send rest of Link State Update. */
1542 if (listcount (ls_upd) > 0)
1543 {
1544 if (oi->type == OSPF_IFTYPE_NBMA)
1545 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1546 else
1547 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1548
1549 list_delete (ls_upd);
1550 }
1551 else
1552 list_free (ls_upd);
1553}
1554
1555/* Get the list of LSAs from Link State Update packet.
1556 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001557static struct list *
paul718e3742002-12-13 20:15:29 +00001558ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1559 struct ospf_interface *oi, size_t size)
1560{
1561 u_int16_t count, sum;
1562 u_int32_t length;
1563 struct lsa_header *lsah;
1564 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001565 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001566
1567 lsas = list_new ();
1568
1569 count = stream_getl (s);
1570 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1571
1572 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001573 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001574 {
1575 lsah = (struct lsa_header *) STREAM_PNT (s);
1576 length = ntohs (lsah->length);
1577
1578 if (length > size)
1579 {
1580 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1581 break;
1582 }
1583
1584 /* Validate the LSA's LS checksum. */
1585 sum = lsah->checksum;
JR Riversd8a4e422012-09-13 17:17:36 +00001586 if (! ospf_lsa_checksum_valid (lsah))
paul718e3742002-12-13 20:15:29 +00001587 {
Jaroslav Fojtik223da1a2011-12-11 18:22:16 +04001588 /* (bug #685) more details in a one-line message make it possible
1589 * to identify problem source on the one hand and to have a better
1590 * chance to compress repeated messages in syslog on the other */
1591 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1592 sum, lsah->checksum, inet_ntoa (lsah->id),
1593 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1594 inet_ntoa (lsah->adv_router));
paul718e3742002-12-13 20:15:29 +00001595 continue;
1596 }
1597
1598 /* Examine the LSA's LS type. */
1599 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1600 {
1601 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1602 continue;
1603 }
1604
1605 /*
1606 * What if the received LSA's age is greater than MaxAge?
1607 * Treat it as a MaxAge case -- endo.
1608 */
1609 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1610 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1611
paul718e3742002-12-13 20:15:29 +00001612 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1613 {
1614#ifdef STRICT_OBIT_USAGE_CHECK
1615 if ((IS_OPAQUE_LSA(lsah->type) &&
1616 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1617 || (! IS_OPAQUE_LSA(lsah->type) &&
1618 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1619 {
1620 /*
1621 * This neighbor must know the exact usage of O-bit;
1622 * the bit will be set in Type-9,10,11 LSAs only.
1623 */
1624 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1625 continue;
1626 }
1627#endif /* STRICT_OBIT_USAGE_CHECK */
1628
1629 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1630 if (lsah->type == OSPF_OPAQUE_AS_LSA
1631 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1632 {
1633 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001634 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 +00001635 continue;
1636 }
1637 }
1638 else if (IS_OPAQUE_LSA(lsah->type))
1639 {
1640 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1641 continue;
1642 }
paul718e3742002-12-13 20:15:29 +00001643
1644 /* Create OSPF LSA instance. */
1645 lsa = ospf_lsa_new ();
1646
1647 /* We may wish to put some error checking if type NSSA comes in
1648 and area not in NSSA mode */
1649 switch (lsah->type)
1650 {
1651 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00001652 case OSPF_OPAQUE_AS_LSA:
1653 lsa->area = NULL;
1654 break;
1655 case OSPF_OPAQUE_LINK_LSA:
1656 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1657 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00001658 default:
1659 lsa->area = oi->area;
1660 break;
1661 }
1662
1663 lsa->data = ospf_lsa_data_new (length);
1664 memcpy (lsa->data, lsah, length);
1665
1666 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001667 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
David Lampartereed3c482015-03-03 08:51:53 +01001668 lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa);
paul718e3742002-12-13 20:15:29 +00001669 listnode_add (lsas, lsa);
1670 }
1671
1672 return lsas;
1673}
1674
1675/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001676static void
hasso52dc7ee2004-09-23 19:18:23 +00001677ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001678{
paul1eb8ef22005-04-07 07:30:20 +00001679 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001680 struct ospf_lsa *lsa;
1681
paul1eb8ef22005-04-07 07:30:20 +00001682 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1683 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001684
1685 list_delete (lsas);
1686}
1687
1688/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001689static void
Michael Rossberg2ef762e2015-07-27 07:56:25 +02001690ospf_ls_upd (struct ospf *ospf, struct ip *iph, struct ospf_header *ospfh,
paul718e3742002-12-13 20:15:29 +00001691 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1692{
1693 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001694 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001695 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001696 struct ospf_lsa *lsa = NULL;
1697 /* unsigned long ls_req_found = 0; */
1698
1699 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1700
1701 /* Increment statistics. */
1702 oi->ls_upd_in++;
1703
1704 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001705 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001706 if (nbr == NULL)
1707 {
1708 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1709 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1710 return;
1711 }
1712
Paul Jakma57c5c652010-01-07 06:12:53 +00001713 /* Add event to thread. */
1714 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1715
paul718e3742002-12-13 20:15:29 +00001716 /* Check neighbor state. */
1717 if (nbr->state < NSM_Exchange)
1718 {
ajs3aa8d5f2004-12-11 18:00:06 +00001719 zlog_warn ("Link State Update: "
1720 "Neighbor[%s] state %s is less than Exchange",
1721 inet_ntoa (ospfh->router_id),
1722 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001723 return;
1724 }
1725
1726 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1727 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1728 * of section 13.
1729 */
1730 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1731
paul718e3742002-12-13 20:15:29 +00001732#define DISCARD_LSA(L,N) {\
1733 if (IS_DEBUG_OSPF_EVENT) \
David Lampartereed3c482015-03-03 08:51:53 +01001734 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p" \
1735 " Type-%d", N, (void *)lsa, (int) lsa->data->type); \
paul718e3742002-12-13 20:15:29 +00001736 ospf_lsa_discard (L); \
1737 continue; }
1738
Andrew Certainf92c57f2012-12-04 13:29:21 -08001739 /* Process each LSA received in the one packet.
1740 *
1741 * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
Andrew Certain0798cee2012-12-04 13:43:42 -08001742 * text below are from the steps in RFC 2328, Section 13.
Andrew Certainf92c57f2012-12-04 13:29:21 -08001743 */
paul1eb8ef22005-04-07 07:30:20 +00001744 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001745 {
1746 struct ospf_lsa *ls_ret, *current;
1747 int ret = 1;
1748
paul718e3742002-12-13 20:15:29 +00001749 if (IS_DEBUG_OSPF_NSSA)
1750 {
1751 char buf1[INET_ADDRSTRLEN];
1752 char buf2[INET_ADDRSTRLEN];
1753 char buf3[INET_ADDRSTRLEN];
1754
ajs2a42e282004-12-08 18:43:03 +00001755 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001756 lsa->data->type,
1757 inet_ntop (AF_INET, &ospfh->router_id,
1758 buf1, INET_ADDRSTRLEN),
1759 inet_ntop (AF_INET, &lsa->data->id,
1760 buf2, INET_ADDRSTRLEN),
1761 inet_ntop (AF_INET, &lsa->data->adv_router,
1762 buf3, INET_ADDRSTRLEN));
1763 }
paul718e3742002-12-13 20:15:29 +00001764
1765 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1766
Andrew Certainf92c57f2012-12-04 13:29:21 -08001767 /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
paul718e3742002-12-13 20:15:29 +00001768
Andrew Certainf92c57f2012-12-04 13:29:21 -08001769 /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
paul718e3742002-12-13 20:15:29 +00001770
Andrew Certainf92c57f2012-12-04 13:29:21 -08001771 /* (3) Do not take in AS External LSAs if we are a stub or NSSA. */
paul718e3742002-12-13 20:15:29 +00001772
1773 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1774
1775 /* Do take in Type-7's if we are an NSSA */
1776
1777 /* If we are also an ABR, later translate them to a Type-5 packet */
1778
1779 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1780 translate them to a separate Type-5 packet. */
1781
1782 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1783 /* Reject from STUB or NSSA */
1784 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1785 {
paul718e3742002-12-13 20:15:29 +00001786 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001787 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001788 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001789 }
1790
paul718e3742002-12-13 20:15:29 +00001791 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1792 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1793 {
paul718e3742002-12-13 20:15:29 +00001794 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001795 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001796 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001797 }
paul718e3742002-12-13 20:15:29 +00001798
David Lamparter23cd8fb2013-08-02 07:27:53 +00001799 /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */
1800 if (lsa->data->type == OSPF_ROUTER_LSA)
1801 if (!IPV4_ADDR_SAME(&lsa->data->id, &lsa->data->adv_router))
1802 {
1803 char buf1[INET_ADDRSTRLEN];
1804 char buf2[INET_ADDRSTRLEN];
1805 char buf3[INET_ADDRSTRLEN];
1806
1807 zlog_err("Incoming Router-LSA from %s with "
1808 "Adv-ID[%s] != LS-ID[%s]",
1809 inet_ntop (AF_INET, &ospfh->router_id,
1810 buf1, INET_ADDRSTRLEN),
1811 inet_ntop (AF_INET, &lsa->data->id,
1812 buf2, INET_ADDRSTRLEN),
1813 inet_ntop (AF_INET, &lsa->data->adv_router,
1814 buf3, INET_ADDRSTRLEN));
1815 zlog_err("OSPF domain compromised by attack or corruption. "
1816 "Verify correct operation of -ALL- OSPF routers.");
1817 DISCARD_LSA (lsa, 0);
1818 }
1819
paul718e3742002-12-13 20:15:29 +00001820 /* Find the LSA in the current database. */
1821
1822 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1823
Andrew Certainf92c57f2012-12-04 13:29:21 -08001824 /* (4) If the LSA's LS age is equal to MaxAge, and there is currently
paul718e3742002-12-13 20:15:29 +00001825 no instance of the LSA in the router's link state database,
1826 and none of router's neighbors are in states Exchange or Loading,
Andrew Certainf92c57f2012-12-04 13:29:21 -08001827 then take the following actions: */
paul718e3742002-12-13 20:15:29 +00001828
1829 if (IS_LSA_MAXAGE (lsa) && !current &&
Christian Franke4c14b7f2013-02-20 10:00:54 +00001830 ospf_check_nbr_status(oi->ospf))
paul718e3742002-12-13 20:15:29 +00001831 {
Andrew Certainf92c57f2012-12-04 13:29:21 -08001832 /* (4a) Response Link State Acknowledgment. */
paul718e3742002-12-13 20:15:29 +00001833 ospf_ls_ack_send (nbr, lsa);
1834
Andrew Certainf92c57f2012-12-04 13:29:21 -08001835 /* (4b) Discard LSA. */
Ayan Banerjeefaf98752012-12-04 10:49:12 -08001836 if (IS_DEBUG_OSPF (lsa, LSA))
1837 {
1838 zlog_debug ("Link State Update[%s]: LS age is equal to MaxAge.",
1839 dump_lsa_key(lsa));
1840 }
paul718e3742002-12-13 20:15:29 +00001841 DISCARD_LSA (lsa, 3);
1842 }
1843
paul718e3742002-12-13 20:15:29 +00001844 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001845 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001846 {
1847 /*
1848 * Even if initial flushing seems to be completed, there might
1849 * be a case that self-originated LSA with MaxAge still remain
1850 * in the routing domain.
1851 * Just send an LSAck message to cease retransmission.
1852 */
1853 if (IS_LSA_MAXAGE (lsa))
1854 {
1855 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1856 ospf_ls_ack_send (nbr, lsa);
1857 ospf_lsa_discard (lsa);
1858
1859 if (current != NULL && ! IS_LSA_MAXAGE (current))
1860 ospf_opaque_lsa_refresh_schedule (current);
1861 continue;
1862 }
1863
1864 /*
1865 * If an instance of self-originated Opaque-LSA is not found
1866 * in the LSDB, there are some possible cases here.
1867 *
1868 * 1) This node lost opaque-capability after restart.
1869 * 2) Else, a part of opaque-type is no more supported.
1870 * 3) Else, a part of opaque-id is no more supported.
1871 *
1872 * Anyway, it is still this node's responsibility to flush it.
1873 * Otherwise, the LSA instance remains in the routing domain
1874 * until its age reaches to MaxAge.
1875 */
paul69310a62005-05-11 18:09:59 +00001876 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001877 if (current == NULL)
1878 {
1879 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001880 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1881 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001882
1883 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001884
1885 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1886 ospf_ls_ack_send (nbr, lsa);
1887
paul718e3742002-12-13 20:15:29 +00001888 continue;
1889 }
1890 }
paul69310a62005-05-11 18:09:59 +00001891
hassocb05eb22004-02-11 21:10:19 +00001892 /* It might be happen that received LSA is self-originated network LSA, but
Andrew Certainf92c57f2012-12-04 13:29:21 -08001893 * router ID is changed. So, we should check if LSA is a network-LSA whose
hassocb05eb22004-02-11 21:10:19 +00001894 * Link State ID is one of the router's own IP interface addresses but whose
1895 * Advertising Router is not equal to the router's own Router ID
1896 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1897 */
1898
1899 if(lsa->data->type == OSPF_NETWORK_LSA)
1900 {
paul1eb8ef22005-04-07 07:30:20 +00001901 struct listnode *oinode, *oinnode;
1902 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001903 int Flag = 0;
1904
paul1eb8ef22005-04-07 07:30:20 +00001905 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001906 {
hassocb05eb22004-02-11 21:10:19 +00001907 if(out_if == NULL)
1908 break;
1909
1910 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1911 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1912 {
1913 if(out_if->network_lsa_self)
1914 {
1915 ospf_lsa_flush_area(lsa,out_if->area);
1916 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001917 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
David Lampartereed3c482015-03-03 08:51:53 +01001918 (void *)lsa, (int) lsa->data->type);
hassocb05eb22004-02-11 21:10:19 +00001919 ospf_lsa_discard (lsa);
1920 Flag = 1;
1921 }
1922 break;
1923 }
1924 }
1925 if(Flag)
1926 continue;
1927 }
paul718e3742002-12-13 20:15:29 +00001928
1929 /* (5) Find the instance of this LSA that is currently contained
1930 in the router's link state database. If there is no
1931 database copy, or the received LSA is more recent than
Andrew Certainf92c57f2012-12-04 13:29:21 -08001932 the database copy the following steps must be performed.
1933 (The sub steps from RFC 2328 section 13 step (5) will be performed in
1934 ospf_flood() ) */
paul718e3742002-12-13 20:15:29 +00001935
1936 if (current == NULL ||
1937 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1938 {
1939 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001940 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001941 DISCARD_LSA (lsa, 4);
1942 continue;
1943 }
1944
1945 /* (6) Else, If there is an instance of the LSA on the sending
1946 neighbor's Link state request list, an error has occurred in
1947 the Database Exchange process. In this case, restart the
1948 Database Exchange process by generating the neighbor event
1949 BadLSReq for the sending neighbor and stop processing the
1950 Link State Update packet. */
1951
1952 if (ospf_ls_request_lookup (nbr, lsa))
1953 {
1954 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001955 zlog_warn("LSA[%s] instance exists on Link state request list",
1956 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001957
1958 /* Clean list of LSAs. */
1959 ospf_upd_list_clean (lsas);
1960 /* this lsa is not on lsas list already. */
1961 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001962 return;
1963 }
1964
1965 /* If the received LSA is the same instance as the database copy
1966 (i.e., neither one is more recent) the following two steps
1967 should be performed: */
1968
1969 if (ret == 0)
1970 {
1971 /* If the LSA is listed in the Link state retransmission list
1972 for the receiving adjacency, the router itself is expecting
1973 an acknowledgment for this LSA. The router should treat the
1974 received LSA as an acknowledgment by removing the LSA from
1975 the Link state retransmission list. This is termed an
1976 "implied acknowledgment". */
1977
1978 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1979
1980 if (ls_ret != NULL)
1981 {
1982 ospf_ls_retransmit_delete (nbr, ls_ret);
1983
1984 /* Delayed acknowledgment sent if advertisement received
1985 from Designated Router, otherwise do nothing. */
1986 if (oi->state == ISM_Backup)
1987 if (NBR_IS_DR (nbr))
1988 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1989
1990 DISCARD_LSA (lsa, 5);
1991 }
1992 else
1993 /* Acknowledge the receipt of the LSA by sending a
1994 Link State Acknowledgment packet back out the receiving
1995 interface. */
1996 {
1997 ospf_ls_ack_send (nbr, lsa);
1998 DISCARD_LSA (lsa, 6);
1999 }
2000 }
2001
2002 /* The database copy is more recent. If the database copy
2003 has LS age equal to MaxAge and LS sequence number equal to
2004 MaxSequenceNumber, simply discard the received LSA without
2005 acknowledging it. (In this case, the LSA's LS sequence number is
2006 wrapping, and the MaxSequenceNumber LSA must be completely
2007 flushed before any new LSA instance can be introduced). */
2008
2009 else if (ret > 0) /* Database copy is more recent */
2010 {
2011 if (IS_LSA_MAXAGE (current) &&
2012 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
2013 {
2014 DISCARD_LSA (lsa, 7);
2015 }
2016 /* Otherwise, as long as the database copy has not been sent in a
2017 Link State Update within the last MinLSArrival seconds, send the
2018 database copy back to the sending neighbor, encapsulated within
2019 a Link State Update Packet. The Link State Update Packet should
2020 be sent directly to the neighbor. In so doing, do not put the
2021 database copy of the LSA on the neighbor's link state
2022 retransmission list, and do not acknowledge the received (less
2023 recent) LSA instance. */
2024 else
2025 {
2026 struct timeval now;
2027
Paul Jakma2518efd2006-08-27 06:49:29 +00002028 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00002029
2030 if (tv_cmp (tv_sub (now, current->tv_orig),
Michael Rossberg2ef762e2015-07-27 07:56:25 +02002031 msec2tv (ospf->min_ls_arrival)) >= 0)
paul718e3742002-12-13 20:15:29 +00002032 /* Trap NSSA type later.*/
2033 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2034 DISCARD_LSA (lsa, 8);
2035 }
2036 }
2037 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002038#undef DISCARD_LSA
2039
paul718e3742002-12-13 20:15:29 +00002040 assert (listcount (lsas) == 0);
2041 list_delete (lsas);
2042}
2043
2044/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002045static void
paul718e3742002-12-13 20:15:29 +00002046ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2047 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2048{
2049 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002050
paul718e3742002-12-13 20:15:29 +00002051 /* increment statistics. */
2052 oi->ls_ack_in++;
2053
pauld3f0d622004-05-05 15:27:15 +00002054 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002055 if (nbr == NULL)
2056 {
2057 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2058 inet_ntoa (ospfh->router_id));
2059 return;
2060 }
2061
Paul Jakma57c5c652010-01-07 06:12:53 +00002062 /* Add event to thread. */
2063 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2064
paul718e3742002-12-13 20:15:29 +00002065 if (nbr->state < NSM_Exchange)
2066 {
ajs3aa8d5f2004-12-11 18:00:06 +00002067 zlog_warn ("Link State Acknowledgment: "
2068 "Neighbor[%s] state %s is less than Exchange",
2069 inet_ntoa (ospfh->router_id),
2070 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002071 return;
2072 }
paul69310a62005-05-11 18:09:59 +00002073
paul718e3742002-12-13 20:15:29 +00002074 while (size >= OSPF_LSA_HEADER_SIZE)
2075 {
2076 struct ospf_lsa *lsa, *lsr;
2077
2078 lsa = ospf_lsa_new ();
2079 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2080
2081 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2082 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002083 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002084
2085 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2086 {
2087 lsa->data = NULL;
2088 ospf_lsa_discard (lsa);
2089 continue;
2090 }
2091
2092 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2093
Lu Feng49d7af12014-02-21 08:11:15 +00002094 if (lsr != NULL && ospf_lsa_more_recent (lsr, lsa) == 0)
Paul Jakmae30677a2015-01-20 15:45:36 +00002095 ospf_ls_retransmit_delete (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002096
2097 lsa->data = NULL;
2098 ospf_lsa_discard (lsa);
2099 }
2100
paul718e3742002-12-13 20:15:29 +00002101 return;
paul718e3742002-12-13 20:15:29 +00002102}
David Lamparter6b0655a2014-06-04 06:53:35 +02002103
ajs038163f2005-02-17 19:55:59 +00002104static struct stream *
ajs5c333492005-02-23 15:43:01 +00002105ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002106{
2107 int ret;
ajs5c333492005-02-23 15:43:01 +00002108 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002109 u_int16_t ip_len;
Paul Jakma9099f9b2016-01-18 10:12:10 +00002110 ifindex_t ifindex = 0;
paul718e3742002-12-13 20:15:29 +00002111 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002112 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002113 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002114 struct msghdr msgh;
2115
paul68defd62004-09-27 07:27:13 +00002116 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002117 msgh.msg_iov = &iov;
2118 msgh.msg_iovlen = 1;
2119 msgh.msg_control = (caddr_t) buff;
2120 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002121
ajs5c333492005-02-23 15:43:01 +00002122 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2123 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002124 {
ajs5c333492005-02-23 15:43:01 +00002125 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2126 return NULL;
2127 }
paul69310a62005-05-11 18:09:59 +00002128 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002129 {
2130 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2131 "(ip header size is %u)",
2132 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002133 return NULL;
2134 }
paul18b12c32004-10-05 14:38:29 +00002135
ajs5c333492005-02-23 15:43:01 +00002136 /* Note that there should not be alignment problems with this assignment
2137 because this is at the beginning of the stream data buffer. */
2138 iph = (struct ip *) STREAM_DATA(ibuf);
2139 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002140
ajs5c333492005-02-23 15:43:01 +00002141 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002142
Dmitrij Tejblumde5ccb92011-12-12 20:30:10 +04002143#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
paul718e3742002-12-13 20:15:29 +00002144 /*
2145 * Kernel network code touches incoming IP header parameters,
2146 * before protocol specific processing.
2147 *
2148 * 1) Convert byteorder to host representation.
2149 * --> ip_len, ip_id, ip_off
2150 *
2151 * 2) Adjust ip_len to strip IP header size!
2152 * --> If user process receives entire IP packet via RAW
2153 * socket, it must consider adding IP header size to
2154 * the "ip_len" field of "ip" structure.
2155 *
2156 * For more details, see <netinet/ip_input.c>.
2157 */
ajs5c333492005-02-23 15:43:01 +00002158 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002159#endif
2160
David BÉRARD0150c9c2010-05-11 10:17:53 +02002161#if defined(__DragonFly__)
2162 /*
2163 * in DragonFly's raw socket, ip_len/ip_off are read
2164 * in network byte order.
2165 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2166 */
2167 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2168#endif
2169
paul863082d2004-08-19 04:43:43 +00002170 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002171
2172 *ifp = if_lookup_by_index (ifindex);
2173
2174 if (ret != ip_len)
2175 {
ajs5c333492005-02-23 15:43:01 +00002176 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2177 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002178 return NULL;
2179 }
2180
2181 return ibuf;
2182}
2183
paul4dadc292005-05-06 21:37:42 +00002184static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002185ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002186 struct ip *iph, struct ospf_header *ospfh)
2187{
2188 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002189 struct ospf_vl_data *vl_data;
2190 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002191 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002192
2193 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2194 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002195 return NULL;
paul718e3742002-12-13 20:15:29 +00002196
pauld3f0d622004-05-05 15:27:15 +00002197 /* look for local OSPF interface matching the destination
2198 * to determine Area ID. We presume therefore the destination address
2199 * is unique, or at least (for "unnumbered" links), not used in other
2200 * areas
2201 */
2202 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2203 iph->ip_dst)) == NULL)
2204 return NULL;
paul718e3742002-12-13 20:15:29 +00002205
paul1eb8ef22005-04-07 07:30:20 +00002206 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002207 {
paul020709f2003-04-04 02:44:16 +00002208 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002209 if (!vl_area)
2210 continue;
2211
2212 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2213 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2214 {
2215 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002216 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002217 IF_NAME (vl_data->vl_oi));
2218 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2219 {
2220 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002221 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002222 return NULL;
2223 }
2224
2225 return vl_data->vl_oi;
2226 }
2227 }
2228
2229 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002230 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002231
pauld3f0d622004-05-05 15:27:15 +00002232 return NULL;
paul718e3742002-12-13 20:15:29 +00002233}
2234
Paul Jakmaf63f06d2011-04-08 12:44:43 +01002235static int
paul718e3742002-12-13 20:15:29 +00002236ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2237{
2238 /* Check match the Area ID of the receiving interface. */
2239 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2240 return 1;
2241
2242 return 0;
2243}
2244
2245/* Unbound socket will accept any Raw IP packets if proto is matched.
2246 To prevent it, compare src IP address and i/f address with masking
2247 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002248static int
paul718e3742002-12-13 20:15:29 +00002249ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2250{
2251 struct in_addr mask, me, him;
2252
2253 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2254 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2255 return 1;
2256
2257 masklen2ip (oi->address->prefixlen, &mask);
2258
2259 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2260 him.s_addr = ip_src.s_addr & mask.s_addr;
2261
2262 if (IPV4_ADDR_SAME (&me, &him))
2263 return 1;
2264
2265 return 0;
2266}
2267
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002268/* Return 1, if the packet is properly authenticated and checksummed,
2269 0 otherwise. In particular, check that AuType header field is valid and
2270 matches the locally configured AuType, and that D.5 requirements are met. */
paul4dadc292005-05-06 21:37:42 +00002271static int
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002272ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +00002273{
paul718e3742002-12-13 20:15:29 +00002274 struct crypt_key *ck;
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002275 u_int16_t iface_auth_type;
2276 u_int16_t pkt_auth_type = ntohs (ospfh->auth_type);
paul718e3742002-12-13 20:15:29 +00002277
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002278 switch (pkt_auth_type)
2279 {
2280 case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
2281 if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))
paul718e3742002-12-13 20:15:29 +00002282 {
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002283 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2284 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null",
2285 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2286 return 0;
paul718e3742002-12-13 20:15:29 +00002287 }
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002288 if (! ospf_check_sum (ospfh))
2289 {
2290 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2291 zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s",
2292 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2293 return 0;
2294 }
2295 return 1;
2296 case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */
2297 if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi)))
2298 {
2299 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2300 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple",
2301 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2302 return 0;
2303 }
2304 if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2305 {
2306 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2307 zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi));
2308 return 0;
2309 }
2310 if (! ospf_check_sum (ospfh))
2311 {
2312 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2313 zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s",
2314 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2315 return 0;
2316 }
2317 return 1;
2318 case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */
2319 if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi)))
2320 {
2321 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2322 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2323 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2324 return 0;
2325 }
2326 if (ospfh->checksum)
2327 {
2328 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2329 zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi));
2330 return 0;
2331 }
2332 /* only MD5 crypto method can pass ospf_packet_examin() */
2333 if
2334 (
2335 NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) ||
2336 ospfh->u.crypt.key_id != ck->key_id ||
2337 /* Condition above uses the last key ID on the list, which is
2338 different from what ospf_crypt_key_lookup() does. A bug? */
2339 ! ospf_check_md5_digest (oi, ospfh)
2340 )
2341 {
2342 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2343 zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi));
2344 return 0;
2345 }
2346 return 1;
2347 default:
2348 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2349 zlog_warn ("interface %s: invalid packet auth-type (%02x)",
2350 IF_NAME (oi), pkt_auth_type);
2351 return 0;
2352 }
paul718e3742002-12-13 20:15:29 +00002353}
2354
paul4dadc292005-05-06 21:37:42 +00002355static int
paul718e3742002-12-13 20:15:29 +00002356ospf_check_sum (struct ospf_header *ospfh)
2357{
2358 u_int32_t ret;
2359 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002360
2361 /* clear auth_data for checksum. */
2362 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2363
2364 /* keep checksum and clear. */
2365 sum = ospfh->checksum;
2366 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2367
2368 /* calculate checksum. */
2369 ret = in_cksum (ospfh, ntohs (ospfh->length));
2370
2371 if (ret != sum)
2372 {
2373 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2374 ret, sum);
2375 return 0;
2376 }
2377
2378 return 1;
2379}
2380
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002381/* Verify, that given link/TOS records are properly sized/aligned and match
2382 Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2383static unsigned
2384ospf_router_lsa_links_examin
2385(
2386 struct router_lsa_link * link,
2387 u_int16_t linkbytes,
2388 const u_int16_t num_links
2389)
2390{
2391 unsigned counted_links = 0, thislinklen;
2392
2393 while (linkbytes)
2394 {
2395 thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
2396 if (thislinklen > linkbytes)
2397 {
2398 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2399 zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
2400 return MSG_NG;
2401 }
2402 link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
2403 linkbytes -= thislinklen;
2404 counted_links++;
2405 }
2406 if (counted_links != num_links)
2407 {
2408 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2409 zlog_debug ("%s: %u link blocks declared, %u present",
2410 __func__, num_links, counted_links);
2411 return MSG_NG;
2412 }
2413 return MSG_OK;
2414}
2415
2416/* Verify, that the given LSA is properly sized/aligned (including type-specific
2417 minimum length constraint). */
2418static unsigned
2419ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
2420{
2421 unsigned ret;
2422 struct router_lsa * rlsa;
2423 if
2424 (
2425 lsah->type < OSPF_MAX_LSA &&
2426 ospf_lsa_minlen[lsah->type] &&
2427 lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
2428 )
2429 {
2430 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2431 zlog_debug ("%s: undersized (%u B) %s",
2432 __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
2433 return MSG_NG;
2434 }
2435 switch (lsah->type)
2436 {
2437 case OSPF_ROUTER_LSA:
2438 /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
2439 if (headeronly)
2440 {
2441 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2442 break;
2443 }
2444 rlsa = (struct router_lsa *) lsah;
2445 ret = ospf_router_lsa_links_examin
2446 (
2447 (struct router_lsa_link *) rlsa->link,
2448 lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
2449 ntohs (rlsa->links) /* 16 bits */
2450 );
2451 break;
2452 case OSPF_AS_EXTERNAL_LSA:
2453 /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
2454 case OSPF_AS_NSSA_LSA:
2455 /* RFC3101 C, idem */
2456 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
2457 break;
2458 /* Following LSA types are considered OK length-wise as soon as their minimum
2459 * length constraint is met and length of the whole LSA is a multiple of 4
2460 * (basic LSA header size is already a multiple of 4). */
2461 case OSPF_NETWORK_LSA:
2462 /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2463 case OSPF_SUMMARY_LSA:
2464 case OSPF_ASBR_SUMMARY_LSA:
2465 /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002466 case OSPF_OPAQUE_LINK_LSA:
2467 case OSPF_OPAQUE_AREA_LSA:
2468 case OSPF_OPAQUE_AS_LSA:
2469 /* RFC5250 A.2, "some number of octets (of application-specific
2470 * data) padded to 32-bit alignment." This is considered equivalent
2471 * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
2472 * file for the detailed analysis of this passage. */
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002473 ret = lsalen % 4 ? MSG_NG : MSG_OK;
2474 break;
2475 default:
2476 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2477 zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
2478 return MSG_NG;
2479 }
2480 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2481 zlog_debug ("%s: alignment error in %s",
2482 __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
2483 return ret;
2484}
2485
2486/* Verify if the provided input buffer is a valid sequence of LSAs. This
2487 includes verification of LSA blocks length/alignment and dispatching
2488 of deeper-level checks. */
2489static unsigned
2490ospf_lsaseq_examin
2491(
2492 struct lsa_header *lsah, /* start of buffered data */
2493 size_t length,
2494 const u_char headeronly,
2495 /* When declared_num_lsas is not 0, compare it to the real number of LSAs
2496 and treat the difference as an error. */
2497 const u_int32_t declared_num_lsas
2498)
2499{
2500 u_int32_t counted_lsas = 0;
2501
2502 while (length)
2503 {
2504 u_int16_t lsalen;
2505 if (length < OSPF_LSA_HEADER_SIZE)
2506 {
2507 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2508 zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
2509 __func__, length, counted_lsas);
2510 return MSG_NG;
2511 }
2512 /* save on ntohs() calls here and in the LSA validator */
2513 lsalen = ntohs (lsah->length);
2514 if (lsalen < OSPF_LSA_HEADER_SIZE)
2515 {
2516 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2517 zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
2518 __func__, counted_lsas, lsalen);
2519 return MSG_NG;
2520 }
2521 if (headeronly)
2522 {
2523 /* less checks here and in ospf_lsa_examin() */
2524 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
2525 {
2526 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2527 zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
2528 return MSG_NG;
2529 }
2530 lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
2531 length -= OSPF_LSA_HEADER_SIZE;
2532 }
2533 else
2534 {
2535 /* make sure the input buffer is deep enough before further checks */
2536 if (lsalen > length)
2537 {
2538 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2539 zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2540 __func__, counted_lsas, lsalen, length);
2541 return MSG_NG;
2542 }
2543 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
2544 {
2545 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2546 zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
2547 return MSG_NG;
2548 }
2549 lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
2550 length -= lsalen;
2551 }
2552 counted_lsas++;
2553 }
2554
2555 if (declared_num_lsas && counted_lsas != declared_num_lsas)
2556 {
2557 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2558 zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
2559 __func__, declared_num_lsas, counted_lsas);
2560 return MSG_NG;
2561 }
2562 return MSG_OK;
2563}
2564
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002565/* Verify a complete OSPF packet for proper sizing/alignment. */
2566static unsigned
2567ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2568{
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002569 u_int16_t bytesdeclared, bytesauth;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002570 unsigned ret;
2571 struct ospf_ls_update * lsupd;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002572
2573 /* Length, 1st approximation. */
2574 if (bytesonwire < OSPF_HEADER_SIZE)
2575 {
2576 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2577 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2578 return MSG_NG;
2579 }
2580 /* Now it is safe to access header fields. Performing length check, allow
2581 * for possible extra bytes of crypto auth/padding, which are not counted
2582 * in the OSPF header "length" field. */
Denis Ovsienkoaee56742012-02-28 15:15:29 +04002583 if (oh->version != OSPF_VERSION)
2584 {
2585 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2586 zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
2587 return MSG_NG;
2588 }
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002589 bytesdeclared = ntohs (oh->length);
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002590 if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2591 bytesauth = 0;
2592 else
2593 {
2594 if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE)
2595 {
2596 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2597 zlog_debug ("%s: unsupported crypto auth length (%u B)",
2598 __func__, oh->u.crypt.auth_data_len);
2599 return MSG_NG;
2600 }
2601 bytesauth = OSPF_AUTH_MD5_SIZE;
2602 }
2603 if (bytesdeclared + bytesauth > bytesonwire)
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002604 {
2605 if (IS_DEBUG_OSPF_PACKET (0, RECV))
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002606 zlog_debug ("%s: packet length error (%u real, %u+%u declared)",
2607 __func__, bytesonwire, bytesdeclared, bytesauth);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002608 return MSG_NG;
2609 }
2610 /* Length, 2nd approximation. The type-specific constraint is checked
2611 against declared length, not amount of bytes on wire. */
2612 if
2613 (
2614 oh->type >= OSPF_MSG_HELLO &&
2615 oh->type <= OSPF_MSG_LS_ACK &&
2616 bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2617 )
2618 {
2619 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2620 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2621 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2622 return MSG_NG;
2623 }
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002624 switch (oh->type)
2625 {
2626 case OSPF_MSG_HELLO:
2627 /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
2628 by N>=0 router-IDs. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002629 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002630 break;
2631 case OSPF_MSG_DB_DESC:
2632 /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
2633 by N>=0 header-only LSAs. */
2634 ret = ospf_lsaseq_examin
2635 (
2636 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002637 bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002638 1, /* header-only LSAs */
2639 0
2640 );
2641 break;
2642 case OSPF_MSG_LS_REQ:
2643 /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002644 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002645 OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
2646 break;
2647 case OSPF_MSG_LS_UPD:
2648 /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
2649 by N>=0 full LSAs (with N declared beforehand). */
2650 lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
2651 ret = ospf_lsaseq_examin
2652 (
2653 (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002654 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002655 0, /* full LSAs */
2656 ntohl (lsupd->num_lsas) /* 32 bits */
2657 );
2658 break;
2659 case OSPF_MSG_LS_ACK:
2660 /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
2661 ret = ospf_lsaseq_examin
2662 (
2663 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002664 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002665 1, /* header-only LSAs */
2666 0
2667 );
2668 break;
2669 default:
2670 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2671 zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
2672 return MSG_NG;
2673 }
2674 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2675 zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
2676 return ret;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002677}
2678
paul718e3742002-12-13 20:15:29 +00002679/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002680static int
paul718e3742002-12-13 20:15:29 +00002681ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2682 struct ip *iph, struct ospf_header *ospfh)
2683{
paul718e3742002-12-13 20:15:29 +00002684 /* Check Area ID. */
2685 if (!ospf_check_area_id (oi, ospfh))
2686 {
2687 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2688 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2689 return -1;
2690 }
2691
2692 /* Check network mask, Silently discarded. */
2693 if (! ospf_check_network_mask (oi, iph->ip_src))
2694 {
2695 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2696 IF_NAME (oi), inet_ntoa (iph->ip_src));
2697 return -1;
2698 }
2699
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002700 /* Check authentication. The function handles logging actions, where required. */
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002701 if (! ospf_check_auth (oi, ospfh))
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002702 return -1;
paul718e3742002-12-13 20:15:29 +00002703
2704 return 0;
2705}
2706
2707/* Starting point of packet process function. */
2708int
2709ospf_read (struct thread *thread)
2710{
2711 int ret;
2712 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002713 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002714 struct ospf_interface *oi;
2715 struct ip *iph;
2716 struct ospf_header *ospfh;
2717 u_int16_t length;
2718 struct interface *ifp;
2719
2720 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002721 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002722
2723 /* prepare for next packet. */
2724 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002725
ajs5c333492005-02-23 15:43:01 +00002726 stream_reset(ospf->ibuf);
2727 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002728 return -1;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002729 /* This raw packet is known to be at least as big as its IP header. */
paul718e3742002-12-13 20:15:29 +00002730
ajs5c333492005-02-23 15:43:01 +00002731 /* Note that there should not be alignment problems with this assignment
2732 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002733 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002734 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002735
paulac191232004-10-22 12:05:17 +00002736 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002737 /* Handle cases where the platform does not support retrieving the ifindex,
2738 and also platforms (such as Solaris 8) that claim to support ifindex
2739 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002740 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002741
pauld3f0d622004-05-05 15:27:15 +00002742 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002743 return 0;
paul718e3742002-12-13 20:15:29 +00002744
2745 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002746 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002747 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002748
paul718e3742002-12-13 20:15:29 +00002749 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002750 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002751 {
pauld3241812003-09-29 12:42:39 +00002752 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2753 {
ajs2a42e282004-12-08 18:43:03 +00002754 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002755 inet_ntoa (iph->ip_src));
2756 }
paul718e3742002-12-13 20:15:29 +00002757 return 0;
2758 }
2759
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002760 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2761 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002762 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002763
paul718e3742002-12-13 20:15:29 +00002764 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002765 if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
2766 return -1;
2767 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002768
2769 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002770 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002771
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002772 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2773 after the passive/backbone/other checks below are passed. These checks
2774 in turn access the fields of unverified "ospfh" structure for their own
2775 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002776
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002777 /* If incoming interface is passive one, ignore it. */
2778 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2779 {
2780 char buf[3][INET_ADDRSTRLEN];
2781
2782 if (IS_DEBUG_OSPF_EVENT)
2783 zlog_debug ("ignoring packet from router %s sent to %s, "
2784 "received on a passive interface, %s",
2785 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2786 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2787 inet_ntop(AF_INET, &oi->address->u.prefix4,
2788 buf[2], sizeof(buf[2])));
2789
2790 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2791 {
2792 /* Try to fix multicast membership.
2793 * Some OS:es may have problems in this area,
2794 * make sure it is removed.
2795 */
2796 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2797 ospf_if_set_multicast(oi);
2798 }
2799 return 0;
2800 }
2801
2802
pauld3f0d622004-05-05 15:27:15 +00002803 /* if no local ospf_interface,
2804 * or header area is backbone but ospf_interface is not
2805 * check for VLINK interface
2806 */
2807 if ( (oi == NULL) ||
2808 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2809 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2810 )
2811 {
2812 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2813 {
Paul Jakma88871b12006-06-15 11:41:19 +00002814 if (IS_DEBUG_OSPF_EVENT)
2815 zlog_debug ("Packet from [%s] received on link %s"
2816 " but no ospf_interface",
2817 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002818 return 0;
2819 }
2820 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002821
pauld3f0d622004-05-05 15:27:15 +00002822 /* else it must be a local ospf interface, check it was received on
2823 * correct link
2824 */
2825 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002826 {
Paul Jakma11637432009-08-11 12:25:42 +01002827 if (IS_DEBUG_OSPF_EVENT)
2828 zlog_warn ("Packet from [%s] received on wrong link %s",
2829 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002830 return 0;
2831 }
ajs847947f2005-02-02 18:38:48 +00002832 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002833 {
ajsba6454e2005-02-08 15:37:30 +00002834 char buf[2][INET_ADDRSTRLEN];
2835 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002836 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002837 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2838 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2839 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002840 /* Fix multicast memberships? */
2841 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002842 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002843 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002844 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002845 if (oi->multicast_memberships)
2846 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002847 return 0;
2848 }
paul718e3742002-12-13 20:15:29 +00002849
2850 /*
2851 * If the received packet is destined for AllDRouters, the packet
2852 * should be accepted only if the received ospf interface state is
2853 * either DR or Backup -- endo.
2854 */
2855 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2856 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2857 {
ajsba6454e2005-02-08 15:37:30 +00002858 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002859 inet_ntoa (iph->ip_src), IF_NAME (oi),
2860 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002861 /* Try to fix multicast membership. */
2862 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2863 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002864 return 0;
2865 }
2866
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002867 /* Verify more OSPF header fields. */
2868 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2869 if (ret < 0)
2870 {
2871 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2872 zlog_debug ("ospf_read[%s]: Header check failed, "
2873 "dropping.",
2874 inet_ntoa (iph->ip_src));
2875 return ret;
2876 }
2877
paul718e3742002-12-13 20:15:29 +00002878 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002879 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2880 {
paul718e3742002-12-13 20:15:29 +00002881 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002882 {
ajs2a42e282004-12-08 18:43:03 +00002883 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002884 ospf_packet_dump (ibuf);
2885 }
paul718e3742002-12-13 20:15:29 +00002886
ajs2a42e282004-12-08 18:43:03 +00002887 zlog_debug ("%s received from [%s] via [%s]",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +04002888 LOOKUP (ospf_packet_type_str, ospfh->type),
paul1aa7b392003-04-08 08:51:58 +00002889 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002890 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2891 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002892
2893 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002894 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002895 }
paul718e3742002-12-13 20:15:29 +00002896
paul9985f832005-02-09 15:51:56 +00002897 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002898
2899 /* Adjust size to message length. */
2900 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2901
2902 /* Read rest of the packet and call each sort of packet routine. */
2903 switch (ospfh->type)
2904 {
2905 case OSPF_MSG_HELLO:
2906 ospf_hello (iph, ospfh, ibuf, oi, length);
2907 break;
2908 case OSPF_MSG_DB_DESC:
2909 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2910 break;
2911 case OSPF_MSG_LS_REQ:
2912 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2913 break;
2914 case OSPF_MSG_LS_UPD:
Michael Rossberg2ef762e2015-07-27 07:56:25 +02002915 ospf_ls_upd (ospf, iph, ospfh, ibuf, oi, length);
paul718e3742002-12-13 20:15:29 +00002916 break;
2917 case OSPF_MSG_LS_ACK:
2918 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2919 break;
2920 default:
2921 zlog (NULL, LOG_WARNING,
2922 "interface %s: OSPF packet header type %d is illegal",
2923 IF_NAME (oi), ospfh->type);
2924 break;
2925 }
2926
paul718e3742002-12-13 20:15:29 +00002927 return 0;
2928}
2929
2930/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002931static void
paul718e3742002-12-13 20:15:29 +00002932ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2933{
2934 struct ospf_header *ospfh;
2935
2936 ospfh = (struct ospf_header *) STREAM_DATA (s);
2937
2938 ospfh->version = (u_char) OSPF_VERSION;
2939 ospfh->type = (u_char) type;
2940
paul68980082003-03-25 05:07:42 +00002941 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002942
2943 ospfh->checksum = 0;
2944 ospfh->area_id = oi->area->area_id;
2945 ospfh->auth_type = htons (ospf_auth_type (oi));
2946
2947 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2948
paul9985f832005-02-09 15:51:56 +00002949 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002950}
2951
2952/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002953static int
paul718e3742002-12-13 20:15:29 +00002954ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2955{
2956 struct crypt_key *ck;
2957
2958 switch (ospf_auth_type (oi))
2959 {
2960 case OSPF_AUTH_NULL:
2961 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2962 break;
2963 case OSPF_AUTH_SIMPLE:
2964 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2965 OSPF_AUTH_SIMPLE_SIZE);
2966 break;
2967 case OSPF_AUTH_CRYPTOGRAPHIC:
2968 /* If key is not set, then set 0. */
2969 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2970 {
2971 ospfh->u.crypt.zero = 0;
2972 ospfh->u.crypt.key_id = 0;
2973 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2974 }
2975 else
2976 {
paul1eb8ef22005-04-07 07:30:20 +00002977 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002978 ospfh->u.crypt.zero = 0;
2979 ospfh->u.crypt.key_id = ck->key_id;
2980 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2981 }
2982 /* note: the seq is done in ospf_make_md5_digest() */
2983 break;
2984 default:
2985 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2986 break;
2987 }
2988
2989 return 0;
2990}
2991
2992/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002993static void
paul718e3742002-12-13 20:15:29 +00002994ospf_fill_header (struct ospf_interface *oi,
2995 struct stream *s, u_int16_t length)
2996{
2997 struct ospf_header *ospfh;
2998
2999 ospfh = (struct ospf_header *) STREAM_DATA (s);
3000
3001 /* Fill length. */
3002 ospfh->length = htons (length);
3003
3004 /* Calculate checksum. */
3005 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
3006 ospfh->checksum = in_cksum (ospfh, length);
3007 else
3008 ospfh->checksum = 0;
3009
3010 /* Add Authentication Data. */
3011 ospf_make_auth (oi, ospfh);
3012}
3013
paul4dadc292005-05-06 21:37:42 +00003014static int
paul718e3742002-12-13 20:15:29 +00003015ospf_make_hello (struct ospf_interface *oi, struct stream *s)
3016{
3017 struct ospf_neighbor *nbr;
3018 struct route_node *rn;
3019 u_int16_t length = OSPF_HELLO_MIN_SIZE;
3020 struct in_addr mask;
3021 unsigned long p;
3022 int flag = 0;
3023
3024 /* Set netmask of interface. */
Vipin Kumarafc9cf92015-05-19 18:03:50 -07003025 if (!(CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED) &&
3026 oi->type == OSPF_IFTYPE_POINTOPOINT) &&
paul718e3742002-12-13 20:15:29 +00003027 oi->type != OSPF_IFTYPE_VIRTUALLINK)
3028 masklen2ip (oi->address->prefixlen, &mask);
3029 else
3030 memset ((char *) &mask, 0, sizeof (struct in_addr));
3031 stream_put_ipv4 (s, mask.s_addr);
3032
3033 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00003034 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
3035 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
3036 else
3037 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00003038
3039 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003040 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00003041 OPTIONS(oi), IF_NAME (oi));
3042
3043 /* Set Options. */
3044 stream_putc (s, OPTIONS (oi));
3045
3046 /* Set Router Priority. */
3047 stream_putc (s, PRIORITY (oi));
3048
3049 /* Set Router Dead Interval. */
3050 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
3051
3052 /* Set Designated Router. */
3053 stream_put_ipv4 (s, DR (oi).s_addr);
3054
paul9985f832005-02-09 15:51:56 +00003055 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003056
3057 /* Set Backup Designated Router. */
3058 stream_put_ipv4 (s, BDR (oi).s_addr);
3059
3060 /* Add neighbor seen. */
3061 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00003062 if ((nbr = rn->info))
3063 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
3064 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
3065 if (nbr->state != NSM_Down) /* This is myself for DR election. */
3066 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003067 {
3068 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00003069 if (nbr->d_router.s_addr != 0
3070 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
3071 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
3072 flag = 1;
paul718e3742002-12-13 20:15:29 +00003073
3074 stream_put_ipv4 (s, nbr->router_id.s_addr);
3075 length += 4;
3076 }
3077
3078 /* Let neighbor generate BackupSeen. */
3079 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00003080 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00003081
3082 return length;
3083}
3084
paul4dadc292005-05-06 21:37:42 +00003085static int
paul718e3742002-12-13 20:15:29 +00003086ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
3087 struct stream *s)
3088{
3089 struct ospf_lsa *lsa;
3090 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
3091 u_char options;
3092 unsigned long pp;
3093 int i;
3094 struct ospf_lsdb *lsdb;
3095
3096 /* Set Interface MTU. */
3097 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3098 stream_putw (s, 0);
3099 else
3100 stream_putw (s, oi->ifp->mtu);
3101
3102 /* Set Options. */
3103 options = OPTIONS (oi);
paul68980082003-03-25 05:07:42 +00003104 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
Lu Feng86ce9512015-01-08 01:39:18 +00003105 SET_FLAG (options, OSPF_OPTION_O);
paul718e3742002-12-13 20:15:29 +00003106 stream_putc (s, options);
3107
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003108 /* DD flags */
paul9985f832005-02-09 15:51:56 +00003109 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003110 stream_putc (s, nbr->dd_flags);
3111
3112 /* Set DD Sequence Number. */
3113 stream_putl (s, nbr->dd_seqnum);
3114
Paul Jakmab5aeb442006-08-30 18:47:37 +00003115 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00003116 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00003117 goto empty;
paul718e3742002-12-13 20:15:29 +00003118
3119 /* Describe LSA Header from Database Summary List. */
3120 lsdb = &nbr->db_sum;
3121
3122 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3123 {
3124 struct route_table *table = lsdb->type[i].db;
3125 struct route_node *rn;
3126
3127 for (rn = route_top (table); rn; rn = route_next (rn))
3128 if ((lsa = rn->info) != NULL)
3129 {
paul718e3742002-12-13 20:15:29 +00003130 if (IS_OPAQUE_LSA (lsa->data->type)
3131 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
3132 {
3133 /* Suppress advertising opaque-informations. */
3134 /* Remove LSA from DB summary list. */
3135 ospf_lsdb_delete (lsdb, lsa);
3136 continue;
3137 }
paul718e3742002-12-13 20:15:29 +00003138
3139 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
3140 {
3141 struct lsa_header *lsah;
3142 u_int16_t ls_age;
3143
3144 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003145 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003146 break;
3147
3148 /* Keep pointer to LS age. */
3149 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00003150 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003151
3152 /* Proceed stream pointer. */
3153 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3154 length += OSPF_LSA_HEADER_SIZE;
3155
3156 /* Set LS age. */
3157 ls_age = LS_AGE (lsa);
3158 lsah->ls_age = htons (ls_age);
3159
3160 }
3161
3162 /* Remove LSA from DB summary list. */
3163 ospf_lsdb_delete (lsdb, lsa);
3164 }
3165 }
3166
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003167 /* Update 'More' bit */
3168 if (ospf_db_summary_isempty (nbr))
3169 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00003170empty:
3171 if (nbr->state >= NSM_Exchange)
3172 {
3173 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
3174 /* Rewrite DD flags */
3175 stream_putc_at (s, pp, nbr->dd_flags);
3176 }
3177 else
3178 {
3179 assert (IS_SET_DD_M(nbr->dd_flags));
3180 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003181 }
paul718e3742002-12-13 20:15:29 +00003182 return length;
3183}
3184
paul4dadc292005-05-06 21:37:42 +00003185static int
paul718e3742002-12-13 20:15:29 +00003186ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
3187 unsigned long delta, struct ospf_neighbor *nbr,
3188 struct ospf_lsa *lsa)
3189{
3190 struct ospf_interface *oi;
3191
3192 oi = nbr->oi;
3193
3194 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003195 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00003196 return 0;
3197
3198 stream_putl (s, lsa->data->type);
3199 stream_put_ipv4 (s, lsa->data->id.s_addr);
3200 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
3201
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003202 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00003203 nbr->ls_req_last = ospf_lsa_lock (lsa);
3204
3205 *length += 12;
3206 return 1;
3207}
3208
paul4dadc292005-05-06 21:37:42 +00003209static int
paul718e3742002-12-13 20:15:29 +00003210ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
3211{
3212 struct ospf_lsa *lsa;
3213 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003214 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00003215 struct route_table *table;
3216 struct route_node *rn;
3217 int i;
3218 struct ospf_lsdb *lsdb;
3219
3220 lsdb = &nbr->ls_req;
3221
3222 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3223 {
3224 table = lsdb->type[i].db;
3225 for (rn = route_top (table); rn; rn = route_next (rn))
3226 if ((lsa = (rn->info)) != NULL)
3227 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
3228 {
3229 route_unlock_node (rn);
3230 break;
3231 }
3232 }
3233 return length;
3234}
3235
paul4dadc292005-05-06 21:37:42 +00003236static int
paul718e3742002-12-13 20:15:29 +00003237ls_age_increment (struct ospf_lsa *lsa, int delay)
3238{
3239 int age;
3240
3241 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
3242
3243 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3244}
3245
paul4dadc292005-05-06 21:37:42 +00003246static int
hasso52dc7ee2004-09-23 19:18:23 +00003247ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003248{
3249 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00003250 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003251 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00003252 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00003253 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003254 unsigned long pp;
3255 int count = 0;
3256
3257 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003258 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00003259
paul9985f832005-02-09 15:51:56 +00003260 pp = stream_get_endp (s);
3261 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003262 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00003263
gdt86f1fd92005-01-10 14:20:43 +00003264 /* Calculate amount of packet usable for data. */
3265 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3266
paul718e3742002-12-13 20:15:29 +00003267 while ((node = listhead (update)) != NULL)
3268 {
3269 struct lsa_header *lsah;
3270 u_int16_t ls_age;
3271
3272 if (IS_DEBUG_OSPF_EVENT)
Dinesh G Dutt1c063342014-09-30 13:04:45 -07003273 zlog_debug ("ospf_make_ls_upd: List Iteration %d", count);
paul718e3742002-12-13 20:15:29 +00003274
paul1eb8ef22005-04-07 07:30:20 +00003275 lsa = listgetdata (node);
3276
paul718e3742002-12-13 20:15:29 +00003277 assert (lsa->data);
3278
paul68b73392004-09-12 14:21:37 +00003279 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00003280 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00003281 break;
3282
paul718e3742002-12-13 20:15:29 +00003283 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00003284 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003285
3286 /* Put LSA to Link State Request. */
3287 stream_put (s, lsa->data, ntohs (lsa->data->length));
3288
3289 /* Set LS age. */
3290 /* each hop must increment an lsa_age by transmit_delay
3291 of OSPF interface */
3292 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3293 lsah->ls_age = htons (ls_age);
3294
3295 length += ntohs (lsa->data->length);
3296 count++;
3297
3298 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003299 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003300 }
3301
3302 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003303 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003304
3305 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003306 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003307 return length;
3308}
3309
paul4dadc292005-05-06 21:37:42 +00003310static int
hasso52dc7ee2004-09-23 19:18:23 +00003311ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003312{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003313 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003314 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003315 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003316 struct ospf_lsa *lsa;
3317
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003318 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003319 {
paul718e3742002-12-13 20:15:29 +00003320 assert (lsa);
3321
gdt86f1fd92005-01-10 14:20:43 +00003322 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003323 break;
3324
3325 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3326 length += OSPF_LSA_HEADER_SIZE;
3327
paul718e3742002-12-13 20:15:29 +00003328 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003329 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003330 }
3331
paul718e3742002-12-13 20:15:29 +00003332 return length;
3333}
3334
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003335static void
3336ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003337{
3338 struct ospf_packet *op;
3339 u_int16_t length = OSPF_HEADER_SIZE;
3340
3341 op = ospf_packet_new (oi->ifp->mtu);
3342
3343 /* Prepare OSPF common header. */
3344 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3345
3346 /* Prepare OSPF Hello body. */
3347 length += ospf_make_hello (oi, op->s);
3348
3349 /* Fill OSPF header. */
3350 ospf_fill_header (oi, op->s, length);
3351
3352 /* Set packet length. */
3353 op->length = length;
3354
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003355 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003356
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003357 /* Add packet to the top of the interface output queue, so that they
3358 * can't get delayed by things like long queues of LS Update packets
3359 */
3360 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003361
3362 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003363 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003364}
3365
paul4dadc292005-05-06 21:37:42 +00003366static void
paul718e3742002-12-13 20:15:29 +00003367ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3368{
3369 struct ospf_interface *oi;
3370
3371 oi = nbr_nbma->oi;
3372 assert(oi);
3373
3374 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003375 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003376 return;
3377
3378 if (oi->type != OSPF_IFTYPE_NBMA)
3379 return;
3380
3381 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3382 return;
3383
3384 if (PRIORITY(oi) == 0)
3385 return;
3386
3387 if (nbr_nbma->priority == 0
3388 && oi->state != ISM_DR && oi->state != ISM_Backup)
3389 return;
3390
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003391 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003392}
3393
3394int
3395ospf_poll_timer (struct thread *thread)
3396{
3397 struct ospf_nbr_nbma *nbr_nbma;
3398
3399 nbr_nbma = THREAD_ARG (thread);
3400 nbr_nbma->t_poll = NULL;
3401
3402 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003403 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003404 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3405
3406 ospf_poll_send (nbr_nbma);
3407
3408 if (nbr_nbma->v_poll > 0)
3409 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3410 nbr_nbma->v_poll);
3411
3412 return 0;
3413}
3414
3415
3416int
3417ospf_hello_reply_timer (struct thread *thread)
3418{
3419 struct ospf_neighbor *nbr;
3420
3421 nbr = THREAD_ARG (thread);
3422 nbr->t_hello_reply = NULL;
3423
3424 assert (nbr->oi);
3425
3426 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003427 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003428 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3429
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003430 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003431
3432 return 0;
3433}
3434
3435/* Send OSPF Hello. */
3436void
3437ospf_hello_send (struct ospf_interface *oi)
3438{
paul718e3742002-12-13 20:15:29 +00003439 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003440 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003441 return;
3442
paul718e3742002-12-13 20:15:29 +00003443 if (oi->type == OSPF_IFTYPE_NBMA)
3444 {
3445 struct ospf_neighbor *nbr;
3446 struct route_node *rn;
3447
3448 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3449 if ((nbr = rn->info))
3450 if (nbr != oi->nbr_self)
3451 if (nbr->state != NSM_Down)
3452 {
3453 /* RFC 2328 Section 9.5.1
3454 If the router is not eligible to become Designated Router,
3455 it must periodically send Hello Packets to both the
3456 Designated Router and the Backup Designated Router (if they
3457 exist). */
3458 if (PRIORITY(oi) == 0 &&
3459 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3460 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3461 continue;
3462
3463 /* If the router is eligible to become Designated Router, it
3464 must periodically send Hello Packets to all neighbors that
3465 are also eligible. In addition, if the router is itself the
3466 Designated Router or Backup Designated Router, it must also
3467 send periodic Hello Packets to all other neighbors. */
3468
3469 if (nbr->priority == 0 && oi->state == ISM_DROther)
3470 continue;
3471 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003472 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003473 }
paul718e3742002-12-13 20:15:29 +00003474 }
3475 else
3476 {
3477 /* Decide destination address. */
3478 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003479 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3480 else
3481 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003482 }
3483}
3484
3485/* Send OSPF Database Description. */
3486void
3487ospf_db_desc_send (struct ospf_neighbor *nbr)
3488{
3489 struct ospf_interface *oi;
3490 struct ospf_packet *op;
3491 u_int16_t length = OSPF_HEADER_SIZE;
3492
3493 oi = nbr->oi;
3494 op = ospf_packet_new (oi->ifp->mtu);
3495
3496 /* Prepare OSPF common header. */
3497 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3498
3499 /* Prepare OSPF Database Description body. */
3500 length += ospf_make_db_desc (oi, nbr, op->s);
3501
3502 /* Fill OSPF header. */
3503 ospf_fill_header (oi, op->s, length);
3504
3505 /* Set packet length. */
3506 op->length = length;
3507
3508 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003509 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3510 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3511 else
3512 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003513
3514 /* Add packet to the interface output queue. */
3515 ospf_packet_add (oi, op);
3516
3517 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003518 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003519
3520 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3521 if (nbr->last_send)
3522 ospf_packet_free (nbr->last_send);
3523 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003524 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003525}
3526
3527/* Re-send Database Description. */
3528void
3529ospf_db_desc_resend (struct ospf_neighbor *nbr)
3530{
3531 struct ospf_interface *oi;
3532
3533 oi = nbr->oi;
3534
3535 /* Add packet to the interface output queue. */
3536 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3537
3538 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003539 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003540}
3541
3542/* Send Link State Request. */
3543void
3544ospf_ls_req_send (struct ospf_neighbor *nbr)
3545{
3546 struct ospf_interface *oi;
3547 struct ospf_packet *op;
3548 u_int16_t length = OSPF_HEADER_SIZE;
3549
3550 oi = nbr->oi;
3551 op = ospf_packet_new (oi->ifp->mtu);
3552
3553 /* Prepare OSPF common header. */
3554 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3555
3556 /* Prepare OSPF Link State Request body. */
3557 length += ospf_make_ls_req (nbr, op->s);
3558 if (length == OSPF_HEADER_SIZE)
3559 {
3560 ospf_packet_free (op);
3561 return;
3562 }
3563
3564 /* Fill OSPF header. */
3565 ospf_fill_header (oi, op->s, length);
3566
3567 /* Set packet length. */
3568 op->length = length;
3569
3570 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003571 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3572 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3573 else
3574 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003575
3576 /* Add packet to the interface output queue. */
3577 ospf_packet_add (oi, op);
3578
3579 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003580 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003581
3582 /* Add Link State Request Retransmission Timer. */
3583 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3584}
3585
3586/* Send Link State Update with an LSA. */
3587void
3588ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3589 int flag)
3590{
hasso52dc7ee2004-09-23 19:18:23 +00003591 struct list *update;
paul718e3742002-12-13 20:15:29 +00003592
3593 update = list_new ();
3594
3595 listnode_add (update, lsa);
3596 ospf_ls_upd_send (nbr, update, flag);
3597
3598 list_delete (update);
3599}
3600
paul68b73392004-09-12 14:21:37 +00003601/* Determine size for packet. Must be at least big enough to accomodate next
3602 * LSA on list, which may be bigger than MTU size.
3603 *
3604 * Return pointer to new ospf_packet
3605 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3606 * on packet sizes (in which case offending LSA is deleted from update list)
3607 */
3608static struct ospf_packet *
3609ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3610{
3611 struct ospf_lsa *lsa;
3612 struct listnode *ln;
3613 size_t size;
3614 static char warned = 0;
3615
paul1eb8ef22005-04-07 07:30:20 +00003616 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003617 assert (lsa->data);
3618
3619 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3620 > ospf_packet_max (oi))
3621 {
3622 if (!warned)
3623 {
3624 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3625 "will need to fragment. Not optimal. Try divide up"
3626 " your network with areas. Use 'debug ospf packet send'"
3627 " to see details, or look at 'show ip ospf database ..'");
3628 warned = 1;
3629 }
3630
3631 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003632 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003633 " %d bytes originated by %s, will be fragmented!",
3634 inet_ntoa (lsa->data->id),
3635 ntohs (lsa->data->length),
3636 inet_ntoa (lsa->data->adv_router));
3637
3638 /*
3639 * Allocate just enough to fit this LSA only, to avoid including other
3640 * LSAs in fragmented LSA Updates.
3641 */
3642 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3643 + OSPF_LS_UPD_MIN_SIZE;
3644 }
3645 else
3646 size = oi->ifp->mtu;
3647
3648 if (size > OSPF_MAX_PACKET_SIZE)
3649 {
3650 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003651 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003652 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003653 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003654 (long int) size);
paul68b73392004-09-12 14:21:37 +00003655 list_delete_node (update, ln);
3656 return NULL;
3657 }
3658
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003659 /* IP header is built up separately by ospf_write(). This means, that we must
3660 * reduce the "affordable" size just calculated by length of an IP header.
3661 * This makes sure, that even if we manage to fill the payload with LSA data
3662 * completely, the final packet (our data plus IP header) still fits into
3663 * outgoing interface MTU. This correction isn't really meaningful for an
3664 * oversized LSA, but for consistency the correction is done for both cases.
3665 *
3666 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3667 */
3668 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003669}
3670
paul718e3742002-12-13 20:15:29 +00003671static void
hasso52dc7ee2004-09-23 19:18:23 +00003672ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003673 struct in_addr addr)
3674{
3675 struct ospf_packet *op;
3676 u_int16_t length = OSPF_HEADER_SIZE;
3677
3678 if (IS_DEBUG_OSPF_EVENT)
Dinesh G Dutt1c063342014-09-30 13:04:45 -07003679 zlog_debug ("listcount = %d, [%s]dst %s", listcount (update), IF_NAME(oi),
3680 inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003681
3682 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003683
3684 /* Prepare OSPF common header. */
3685 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3686
paul59ea14c2004-07-14 20:50:36 +00003687 /* Prepare OSPF Link State Update body.
3688 * Includes Type-7 translation.
3689 */
paul718e3742002-12-13 20:15:29 +00003690 length += ospf_make_ls_upd (oi, update, op->s);
3691
3692 /* Fill OSPF header. */
3693 ospf_fill_header (oi, op->s, length);
3694
3695 /* Set packet length. */
3696 op->length = length;
3697
3698 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003699 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3700 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3701 else
3702 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003703
3704 /* Add packet to the interface output queue. */
3705 ospf_packet_add (oi, op);
3706
3707 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003708 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003709}
3710
3711static int
3712ospf_ls_upd_send_queue_event (struct thread *thread)
3713{
3714 struct ospf_interface *oi = THREAD_ARG(thread);
3715 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003716 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003717 struct list *update;
paul68b73392004-09-12 14:21:37 +00003718 char again = 0;
paul718e3742002-12-13 20:15:29 +00003719
3720 oi->t_ls_upd_event = NULL;
3721
3722 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003723 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003724
paul736d3442003-07-24 23:22:57 +00003725 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003726 {
paul736d3442003-07-24 23:22:57 +00003727 rnext = route_next (rn);
3728
paul718e3742002-12-13 20:15:29 +00003729 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003730 continue;
paul68b73392004-09-12 14:21:37 +00003731
3732 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003733
paul48fe13b2004-07-27 17:40:44 +00003734 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003735
paul68b73392004-09-12 14:21:37 +00003736 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003737 if (listcount(update) == 0)
3738 {
3739 list_delete (rn->info);
3740 rn->info = NULL;
3741 route_unlock_node (rn);
3742 }
3743 else
paul68b73392004-09-12 14:21:37 +00003744 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003745 }
3746
3747 if (again != 0)
3748 {
3749 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003750 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003751 " %d nodes to try again, raising new event", again);
3752 oi->t_ls_upd_event =
3753 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003754 }
3755
3756 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003757 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003758
paul718e3742002-12-13 20:15:29 +00003759 return 0;
3760}
3761
3762void
hasso52dc7ee2004-09-23 19:18:23 +00003763ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003764{
3765 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003766 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003767 struct prefix_ipv4 p;
3768 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003769 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003770
3771 oi = nbr->oi;
3772
3773 p.family = AF_INET;
3774 p.prefixlen = IPV4_MAX_BITLEN;
3775
3776 /* Decide destination address. */
3777 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3778 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003779 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3780 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003781 else if (flag == OSPF_SEND_PACKET_DIRECT)
3782 p.prefix = nbr->address.u.prefix4;
3783 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3784 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003785 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3786 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003787 else
3788 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3789
3790 if (oi->type == OSPF_IFTYPE_NBMA)
3791 {
3792 if (flag == OSPF_SEND_PACKET_INDIRECT)
3793 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3794 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3795 zlog_warn ("* LS-Update is sent to myself.");
3796 }
3797
3798 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3799
3800 if (rn->info == NULL)
3801 rn->info = list_new ();
Joakim Tjernlund4eaecdc2010-03-08 13:58:13 +01003802 else
3803 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00003804
paul1eb8ef22005-04-07 07:30:20 +00003805 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003806 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003807
3808 if (oi->t_ls_upd_event == NULL)
3809 oi->t_ls_upd_event =
3810 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3811}
3812
3813static void
hasso52dc7ee2004-09-23 19:18:23 +00003814ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3815 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003816{
3817 struct ospf_packet *op;
3818 u_int16_t length = OSPF_HEADER_SIZE;
3819
3820 op = ospf_packet_new (oi->ifp->mtu);
3821
3822 /* Prepare OSPF common header. */
3823 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3824
3825 /* Prepare OSPF Link State Acknowledgment body. */
3826 length += ospf_make_ls_ack (oi, ack, op->s);
3827
3828 /* Fill OSPF header. */
3829 ospf_fill_header (oi, op->s, length);
3830
3831 /* Set packet length. */
3832 op->length = length;
3833
Vipin Kumar45af55a2015-05-19 18:03:43 -07003834 /* Decide destination address. */
3835 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3836 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3837 else
3838 op->dst.s_addr = dst.s_addr;
3839
paul718e3742002-12-13 20:15:29 +00003840 /* Add packet to the interface output queue. */
3841 ospf_packet_add (oi, op);
3842
3843 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003844 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003845}
3846
3847static int
3848ospf_ls_ack_send_event (struct thread *thread)
3849{
3850 struct ospf_interface *oi = THREAD_ARG (thread);
3851
3852 oi->t_ls_ack_direct = NULL;
3853
3854 while (listcount (oi->ls_ack_direct.ls_ack))
3855 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3856 oi->ls_ack_direct.dst);
3857
3858 return 0;
3859}
3860
3861void
3862ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3863{
3864 struct ospf_interface *oi = nbr->oi;
3865
3866 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3867 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3868
3869 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3870
3871 if (oi->t_ls_ack_direct == NULL)
3872 oi->t_ls_ack_direct =
3873 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3874}
3875
3876/* Send Link State Acknowledgment delayed. */
3877void
3878ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3879{
3880 struct in_addr dst;
3881
3882 /* Decide destination address. */
3883 /* RFC2328 Section 13.5 On non-broadcast
3884 networks, delayed Link State Acknowledgment packets must be
3885 unicast separately over each adjacency (i.e., neighbor whose
3886 state is >= Exchange). */
3887 if (oi->type == OSPF_IFTYPE_NBMA)
3888 {
3889 struct ospf_neighbor *nbr;
3890 struct route_node *rn;
3891
3892 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3893 if ((nbr = rn->info) != NULL)
3894 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3895 while (listcount (oi->ls_ack))
3896 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3897 return;
3898 }
3899 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3900 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3901 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3902 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3903 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3904 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003905 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3906 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003907 else
3908 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3909
3910 while (listcount (oi->ls_ack))
3911 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3912}