blob: 25f70bba8041ba9bd8d7017da4c3ed214584a416 [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
885 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
886 {
887 /*
888 * This router does not support non-zero TOS.
889 * Drop this Hello packet not to establish neighbor relationship.
890 */
891 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
892 inet_ntoa (ospfh->router_id));
893 return;
894 }
895#endif /* REJECT_IF_TBIT_ON */
896
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
1234 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1235 {
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. */
3025 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
3026 oi->type != OSPF_IFTYPE_VIRTUALLINK)
3027 masklen2ip (oi->address->prefixlen, &mask);
3028 else
3029 memset ((char *) &mask, 0, sizeof (struct in_addr));
3030 stream_put_ipv4 (s, mask.s_addr);
3031
3032 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00003033 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
3034 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
3035 else
3036 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00003037
3038 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003039 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00003040 OPTIONS(oi), IF_NAME (oi));
3041
3042 /* Set Options. */
3043 stream_putc (s, OPTIONS (oi));
3044
3045 /* Set Router Priority. */
3046 stream_putc (s, PRIORITY (oi));
3047
3048 /* Set Router Dead Interval. */
3049 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
3050
3051 /* Set Designated Router. */
3052 stream_put_ipv4 (s, DR (oi).s_addr);
3053
paul9985f832005-02-09 15:51:56 +00003054 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003055
3056 /* Set Backup Designated Router. */
3057 stream_put_ipv4 (s, BDR (oi).s_addr);
3058
3059 /* Add neighbor seen. */
3060 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00003061 if ((nbr = rn->info))
3062 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
3063 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
3064 if (nbr->state != NSM_Down) /* This is myself for DR election. */
3065 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003066 {
3067 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00003068 if (nbr->d_router.s_addr != 0
3069 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
3070 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
3071 flag = 1;
paul718e3742002-12-13 20:15:29 +00003072
3073 stream_put_ipv4 (s, nbr->router_id.s_addr);
3074 length += 4;
3075 }
3076
3077 /* Let neighbor generate BackupSeen. */
3078 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00003079 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00003080
3081 return length;
3082}
3083
paul4dadc292005-05-06 21:37:42 +00003084static int
paul718e3742002-12-13 20:15:29 +00003085ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
3086 struct stream *s)
3087{
3088 struct ospf_lsa *lsa;
3089 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
3090 u_char options;
3091 unsigned long pp;
3092 int i;
3093 struct ospf_lsdb *lsdb;
3094
3095 /* Set Interface MTU. */
3096 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3097 stream_putw (s, 0);
3098 else
3099 stream_putw (s, oi->ifp->mtu);
3100
3101 /* Set Options. */
3102 options = OPTIONS (oi);
paul68980082003-03-25 05:07:42 +00003103 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
Lu Feng86ce9512015-01-08 01:39:18 +00003104 SET_FLAG (options, OSPF_OPTION_O);
paul718e3742002-12-13 20:15:29 +00003105 stream_putc (s, options);
3106
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003107 /* DD flags */
paul9985f832005-02-09 15:51:56 +00003108 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003109 stream_putc (s, nbr->dd_flags);
3110
3111 /* Set DD Sequence Number. */
3112 stream_putl (s, nbr->dd_seqnum);
3113
Paul Jakmab5aeb442006-08-30 18:47:37 +00003114 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00003115 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00003116 goto empty;
paul718e3742002-12-13 20:15:29 +00003117
3118 /* Describe LSA Header from Database Summary List. */
3119 lsdb = &nbr->db_sum;
3120
3121 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3122 {
3123 struct route_table *table = lsdb->type[i].db;
3124 struct route_node *rn;
3125
3126 for (rn = route_top (table); rn; rn = route_next (rn))
3127 if ((lsa = rn->info) != NULL)
3128 {
paul718e3742002-12-13 20:15:29 +00003129 if (IS_OPAQUE_LSA (lsa->data->type)
3130 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
3131 {
3132 /* Suppress advertising opaque-informations. */
3133 /* Remove LSA from DB summary list. */
3134 ospf_lsdb_delete (lsdb, lsa);
3135 continue;
3136 }
paul718e3742002-12-13 20:15:29 +00003137
3138 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
3139 {
3140 struct lsa_header *lsah;
3141 u_int16_t ls_age;
3142
3143 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003144 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003145 break;
3146
3147 /* Keep pointer to LS age. */
3148 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00003149 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003150
3151 /* Proceed stream pointer. */
3152 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3153 length += OSPF_LSA_HEADER_SIZE;
3154
3155 /* Set LS age. */
3156 ls_age = LS_AGE (lsa);
3157 lsah->ls_age = htons (ls_age);
3158
3159 }
3160
3161 /* Remove LSA from DB summary list. */
3162 ospf_lsdb_delete (lsdb, lsa);
3163 }
3164 }
3165
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003166 /* Update 'More' bit */
3167 if (ospf_db_summary_isempty (nbr))
3168 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00003169empty:
3170 if (nbr->state >= NSM_Exchange)
3171 {
3172 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
3173 /* Rewrite DD flags */
3174 stream_putc_at (s, pp, nbr->dd_flags);
3175 }
3176 else
3177 {
3178 assert (IS_SET_DD_M(nbr->dd_flags));
3179 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003180 }
paul718e3742002-12-13 20:15:29 +00003181 return length;
3182}
3183
paul4dadc292005-05-06 21:37:42 +00003184static int
paul718e3742002-12-13 20:15:29 +00003185ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
3186 unsigned long delta, struct ospf_neighbor *nbr,
3187 struct ospf_lsa *lsa)
3188{
3189 struct ospf_interface *oi;
3190
3191 oi = nbr->oi;
3192
3193 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003194 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00003195 return 0;
3196
3197 stream_putl (s, lsa->data->type);
3198 stream_put_ipv4 (s, lsa->data->id.s_addr);
3199 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
3200
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003201 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00003202 nbr->ls_req_last = ospf_lsa_lock (lsa);
3203
3204 *length += 12;
3205 return 1;
3206}
3207
paul4dadc292005-05-06 21:37:42 +00003208static int
paul718e3742002-12-13 20:15:29 +00003209ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
3210{
3211 struct ospf_lsa *lsa;
3212 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003213 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00003214 struct route_table *table;
3215 struct route_node *rn;
3216 int i;
3217 struct ospf_lsdb *lsdb;
3218
3219 lsdb = &nbr->ls_req;
3220
3221 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3222 {
3223 table = lsdb->type[i].db;
3224 for (rn = route_top (table); rn; rn = route_next (rn))
3225 if ((lsa = (rn->info)) != NULL)
3226 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
3227 {
3228 route_unlock_node (rn);
3229 break;
3230 }
3231 }
3232 return length;
3233}
3234
paul4dadc292005-05-06 21:37:42 +00003235static int
paul718e3742002-12-13 20:15:29 +00003236ls_age_increment (struct ospf_lsa *lsa, int delay)
3237{
3238 int age;
3239
3240 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
3241
3242 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3243}
3244
paul4dadc292005-05-06 21:37:42 +00003245static int
hasso52dc7ee2004-09-23 19:18:23 +00003246ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003247{
3248 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00003249 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003250 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00003251 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00003252 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003253 unsigned long pp;
3254 int count = 0;
3255
3256 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003257 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00003258
paul9985f832005-02-09 15:51:56 +00003259 pp = stream_get_endp (s);
3260 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003261 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00003262
gdt86f1fd92005-01-10 14:20:43 +00003263 /* Calculate amount of packet usable for data. */
3264 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3265
paul718e3742002-12-13 20:15:29 +00003266 while ((node = listhead (update)) != NULL)
3267 {
3268 struct lsa_header *lsah;
3269 u_int16_t ls_age;
3270
3271 if (IS_DEBUG_OSPF_EVENT)
Dinesh G Dutt1c063342014-09-30 13:04:45 -07003272 zlog_debug ("ospf_make_ls_upd: List Iteration %d", count);
paul718e3742002-12-13 20:15:29 +00003273
paul1eb8ef22005-04-07 07:30:20 +00003274 lsa = listgetdata (node);
3275
paul718e3742002-12-13 20:15:29 +00003276 assert (lsa->data);
3277
paul68b73392004-09-12 14:21:37 +00003278 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00003279 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00003280 break;
3281
paul718e3742002-12-13 20:15:29 +00003282 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00003283 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003284
3285 /* Put LSA to Link State Request. */
3286 stream_put (s, lsa->data, ntohs (lsa->data->length));
3287
3288 /* Set LS age. */
3289 /* each hop must increment an lsa_age by transmit_delay
3290 of OSPF interface */
3291 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3292 lsah->ls_age = htons (ls_age);
3293
3294 length += ntohs (lsa->data->length);
3295 count++;
3296
3297 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003298 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003299 }
3300
3301 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003302 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003303
3304 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003305 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003306 return length;
3307}
3308
paul4dadc292005-05-06 21:37:42 +00003309static int
hasso52dc7ee2004-09-23 19:18:23 +00003310ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003311{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003312 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003313 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003314 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003315 struct ospf_lsa *lsa;
3316
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003317 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003318 {
paul718e3742002-12-13 20:15:29 +00003319 assert (lsa);
3320
gdt86f1fd92005-01-10 14:20:43 +00003321 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003322 break;
3323
3324 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3325 length += OSPF_LSA_HEADER_SIZE;
3326
paul718e3742002-12-13 20:15:29 +00003327 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003328 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003329 }
3330
paul718e3742002-12-13 20:15:29 +00003331 return length;
3332}
3333
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003334static void
3335ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003336{
3337 struct ospf_packet *op;
3338 u_int16_t length = OSPF_HEADER_SIZE;
3339
3340 op = ospf_packet_new (oi->ifp->mtu);
3341
3342 /* Prepare OSPF common header. */
3343 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3344
3345 /* Prepare OSPF Hello body. */
3346 length += ospf_make_hello (oi, op->s);
3347
3348 /* Fill OSPF header. */
3349 ospf_fill_header (oi, op->s, length);
3350
3351 /* Set packet length. */
3352 op->length = length;
3353
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003354 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003355
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003356 /* Add packet to the top of the interface output queue, so that they
3357 * can't get delayed by things like long queues of LS Update packets
3358 */
3359 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003360
3361 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003362 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003363}
3364
paul4dadc292005-05-06 21:37:42 +00003365static void
paul718e3742002-12-13 20:15:29 +00003366ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3367{
3368 struct ospf_interface *oi;
3369
3370 oi = nbr_nbma->oi;
3371 assert(oi);
3372
3373 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003374 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003375 return;
3376
3377 if (oi->type != OSPF_IFTYPE_NBMA)
3378 return;
3379
3380 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3381 return;
3382
3383 if (PRIORITY(oi) == 0)
3384 return;
3385
3386 if (nbr_nbma->priority == 0
3387 && oi->state != ISM_DR && oi->state != ISM_Backup)
3388 return;
3389
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003390 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003391}
3392
3393int
3394ospf_poll_timer (struct thread *thread)
3395{
3396 struct ospf_nbr_nbma *nbr_nbma;
3397
3398 nbr_nbma = THREAD_ARG (thread);
3399 nbr_nbma->t_poll = NULL;
3400
3401 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003402 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003403 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3404
3405 ospf_poll_send (nbr_nbma);
3406
3407 if (nbr_nbma->v_poll > 0)
3408 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3409 nbr_nbma->v_poll);
3410
3411 return 0;
3412}
3413
3414
3415int
3416ospf_hello_reply_timer (struct thread *thread)
3417{
3418 struct ospf_neighbor *nbr;
3419
3420 nbr = THREAD_ARG (thread);
3421 nbr->t_hello_reply = NULL;
3422
3423 assert (nbr->oi);
3424
3425 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003426 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003427 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3428
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003429 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003430
3431 return 0;
3432}
3433
3434/* Send OSPF Hello. */
3435void
3436ospf_hello_send (struct ospf_interface *oi)
3437{
paul718e3742002-12-13 20:15:29 +00003438 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003439 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003440 return;
3441
paul718e3742002-12-13 20:15:29 +00003442 if (oi->type == OSPF_IFTYPE_NBMA)
3443 {
3444 struct ospf_neighbor *nbr;
3445 struct route_node *rn;
3446
3447 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3448 if ((nbr = rn->info))
3449 if (nbr != oi->nbr_self)
3450 if (nbr->state != NSM_Down)
3451 {
3452 /* RFC 2328 Section 9.5.1
3453 If the router is not eligible to become Designated Router,
3454 it must periodically send Hello Packets to both the
3455 Designated Router and the Backup Designated Router (if they
3456 exist). */
3457 if (PRIORITY(oi) == 0 &&
3458 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3459 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3460 continue;
3461
3462 /* If the router is eligible to become Designated Router, it
3463 must periodically send Hello Packets to all neighbors that
3464 are also eligible. In addition, if the router is itself the
3465 Designated Router or Backup Designated Router, it must also
3466 send periodic Hello Packets to all other neighbors. */
3467
3468 if (nbr->priority == 0 && oi->state == ISM_DROther)
3469 continue;
3470 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003471 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003472 }
paul718e3742002-12-13 20:15:29 +00003473 }
3474 else
3475 {
3476 /* Decide destination address. */
3477 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003478 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3479 else
3480 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003481 }
3482}
3483
3484/* Send OSPF Database Description. */
3485void
3486ospf_db_desc_send (struct ospf_neighbor *nbr)
3487{
3488 struct ospf_interface *oi;
3489 struct ospf_packet *op;
3490 u_int16_t length = OSPF_HEADER_SIZE;
3491
3492 oi = nbr->oi;
3493 op = ospf_packet_new (oi->ifp->mtu);
3494
3495 /* Prepare OSPF common header. */
3496 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3497
3498 /* Prepare OSPF Database Description body. */
3499 length += ospf_make_db_desc (oi, nbr, op->s);
3500
3501 /* Fill OSPF header. */
3502 ospf_fill_header (oi, op->s, length);
3503
3504 /* Set packet length. */
3505 op->length = length;
3506
3507 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003508 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3509 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3510 else
3511 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003512
3513 /* Add packet to the interface output queue. */
3514 ospf_packet_add (oi, op);
3515
3516 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003517 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003518
3519 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3520 if (nbr->last_send)
3521 ospf_packet_free (nbr->last_send);
3522 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003523 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003524}
3525
3526/* Re-send Database Description. */
3527void
3528ospf_db_desc_resend (struct ospf_neighbor *nbr)
3529{
3530 struct ospf_interface *oi;
3531
3532 oi = nbr->oi;
3533
3534 /* Add packet to the interface output queue. */
3535 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3536
3537 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003538 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003539}
3540
3541/* Send Link State Request. */
3542void
3543ospf_ls_req_send (struct ospf_neighbor *nbr)
3544{
3545 struct ospf_interface *oi;
3546 struct ospf_packet *op;
3547 u_int16_t length = OSPF_HEADER_SIZE;
3548
3549 oi = nbr->oi;
3550 op = ospf_packet_new (oi->ifp->mtu);
3551
3552 /* Prepare OSPF common header. */
3553 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3554
3555 /* Prepare OSPF Link State Request body. */
3556 length += ospf_make_ls_req (nbr, op->s);
3557 if (length == OSPF_HEADER_SIZE)
3558 {
3559 ospf_packet_free (op);
3560 return;
3561 }
3562
3563 /* Fill OSPF header. */
3564 ospf_fill_header (oi, op->s, length);
3565
3566 /* Set packet length. */
3567 op->length = length;
3568
3569 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003570 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3571 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3572 else
3573 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003574
3575 /* Add packet to the interface output queue. */
3576 ospf_packet_add (oi, op);
3577
3578 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003579 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003580
3581 /* Add Link State Request Retransmission Timer. */
3582 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3583}
3584
3585/* Send Link State Update with an LSA. */
3586void
3587ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3588 int flag)
3589{
hasso52dc7ee2004-09-23 19:18:23 +00003590 struct list *update;
paul718e3742002-12-13 20:15:29 +00003591
3592 update = list_new ();
3593
3594 listnode_add (update, lsa);
3595 ospf_ls_upd_send (nbr, update, flag);
3596
3597 list_delete (update);
3598}
3599
paul68b73392004-09-12 14:21:37 +00003600/* Determine size for packet. Must be at least big enough to accomodate next
3601 * LSA on list, which may be bigger than MTU size.
3602 *
3603 * Return pointer to new ospf_packet
3604 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3605 * on packet sizes (in which case offending LSA is deleted from update list)
3606 */
3607static struct ospf_packet *
3608ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3609{
3610 struct ospf_lsa *lsa;
3611 struct listnode *ln;
3612 size_t size;
3613 static char warned = 0;
3614
paul1eb8ef22005-04-07 07:30:20 +00003615 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003616 assert (lsa->data);
3617
3618 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3619 > ospf_packet_max (oi))
3620 {
3621 if (!warned)
3622 {
3623 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3624 "will need to fragment. Not optimal. Try divide up"
3625 " your network with areas. Use 'debug ospf packet send'"
3626 " to see details, or look at 'show ip ospf database ..'");
3627 warned = 1;
3628 }
3629
3630 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003631 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003632 " %d bytes originated by %s, will be fragmented!",
3633 inet_ntoa (lsa->data->id),
3634 ntohs (lsa->data->length),
3635 inet_ntoa (lsa->data->adv_router));
3636
3637 /*
3638 * Allocate just enough to fit this LSA only, to avoid including other
3639 * LSAs in fragmented LSA Updates.
3640 */
3641 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3642 + OSPF_LS_UPD_MIN_SIZE;
3643 }
3644 else
3645 size = oi->ifp->mtu;
3646
3647 if (size > OSPF_MAX_PACKET_SIZE)
3648 {
3649 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003650 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003651 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003652 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003653 (long int) size);
paul68b73392004-09-12 14:21:37 +00003654 list_delete_node (update, ln);
3655 return NULL;
3656 }
3657
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003658 /* IP header is built up separately by ospf_write(). This means, that we must
3659 * reduce the "affordable" size just calculated by length of an IP header.
3660 * This makes sure, that even if we manage to fill the payload with LSA data
3661 * completely, the final packet (our data plus IP header) still fits into
3662 * outgoing interface MTU. This correction isn't really meaningful for an
3663 * oversized LSA, but for consistency the correction is done for both cases.
3664 *
3665 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3666 */
3667 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003668}
3669
paul718e3742002-12-13 20:15:29 +00003670static void
hasso52dc7ee2004-09-23 19:18:23 +00003671ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003672 struct in_addr addr)
3673{
3674 struct ospf_packet *op;
3675 u_int16_t length = OSPF_HEADER_SIZE;
3676
3677 if (IS_DEBUG_OSPF_EVENT)
Dinesh G Dutt1c063342014-09-30 13:04:45 -07003678 zlog_debug ("listcount = %d, [%s]dst %s", listcount (update), IF_NAME(oi),
3679 inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003680
3681 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003682
3683 /* Prepare OSPF common header. */
3684 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3685
paul59ea14c2004-07-14 20:50:36 +00003686 /* Prepare OSPF Link State Update body.
3687 * Includes Type-7 translation.
3688 */
paul718e3742002-12-13 20:15:29 +00003689 length += ospf_make_ls_upd (oi, update, op->s);
3690
3691 /* Fill OSPF header. */
3692 ospf_fill_header (oi, op->s, length);
3693
3694 /* Set packet length. */
3695 op->length = length;
3696
3697 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003698 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3699 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3700 else
3701 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003702
3703 /* Add packet to the interface output queue. */
3704 ospf_packet_add (oi, op);
3705
3706 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003707 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003708}
3709
3710static int
3711ospf_ls_upd_send_queue_event (struct thread *thread)
3712{
3713 struct ospf_interface *oi = THREAD_ARG(thread);
3714 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003715 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003716 struct list *update;
paul68b73392004-09-12 14:21:37 +00003717 char again = 0;
paul718e3742002-12-13 20:15:29 +00003718
3719 oi->t_ls_upd_event = NULL;
3720
3721 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003722 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003723
paul736d3442003-07-24 23:22:57 +00003724 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003725 {
paul736d3442003-07-24 23:22:57 +00003726 rnext = route_next (rn);
3727
paul718e3742002-12-13 20:15:29 +00003728 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003729 continue;
paul68b73392004-09-12 14:21:37 +00003730
3731 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003732
paul48fe13b2004-07-27 17:40:44 +00003733 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003734
paul68b73392004-09-12 14:21:37 +00003735 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003736 if (listcount(update) == 0)
3737 {
3738 list_delete (rn->info);
3739 rn->info = NULL;
3740 route_unlock_node (rn);
3741 }
3742 else
paul68b73392004-09-12 14:21:37 +00003743 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003744 }
3745
3746 if (again != 0)
3747 {
3748 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003749 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003750 " %d nodes to try again, raising new event", again);
3751 oi->t_ls_upd_event =
3752 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003753 }
3754
3755 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003756 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003757
paul718e3742002-12-13 20:15:29 +00003758 return 0;
3759}
3760
3761void
hasso52dc7ee2004-09-23 19:18:23 +00003762ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003763{
3764 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003765 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003766 struct prefix_ipv4 p;
3767 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003768 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003769
3770 oi = nbr->oi;
3771
3772 p.family = AF_INET;
3773 p.prefixlen = IPV4_MAX_BITLEN;
3774
3775 /* Decide destination address. */
3776 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3777 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003778 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3779 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003780 else if (flag == OSPF_SEND_PACKET_DIRECT)
3781 p.prefix = nbr->address.u.prefix4;
3782 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3783 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003784 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3785 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003786 else
3787 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3788
3789 if (oi->type == OSPF_IFTYPE_NBMA)
3790 {
3791 if (flag == OSPF_SEND_PACKET_INDIRECT)
3792 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3793 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3794 zlog_warn ("* LS-Update is sent to myself.");
3795 }
3796
3797 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3798
3799 if (rn->info == NULL)
3800 rn->info = list_new ();
Joakim Tjernlund4eaecdc2010-03-08 13:58:13 +01003801 else
3802 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00003803
paul1eb8ef22005-04-07 07:30:20 +00003804 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003805 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003806
3807 if (oi->t_ls_upd_event == NULL)
3808 oi->t_ls_upd_event =
3809 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3810}
3811
3812static void
hasso52dc7ee2004-09-23 19:18:23 +00003813ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3814 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003815{
3816 struct ospf_packet *op;
3817 u_int16_t length = OSPF_HEADER_SIZE;
3818
3819 op = ospf_packet_new (oi->ifp->mtu);
3820
3821 /* Prepare OSPF common header. */
3822 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3823
3824 /* Prepare OSPF Link State Acknowledgment body. */
3825 length += ospf_make_ls_ack (oi, ack, op->s);
3826
3827 /* Fill OSPF header. */
3828 ospf_fill_header (oi, op->s, length);
3829
3830 /* Set packet length. */
3831 op->length = length;
3832
3833 /* Set destination IP address. */
3834 op->dst = dst;
3835
3836 /* Add packet to the interface output queue. */
3837 ospf_packet_add (oi, op);
3838
3839 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003840 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003841}
3842
3843static int
3844ospf_ls_ack_send_event (struct thread *thread)
3845{
3846 struct ospf_interface *oi = THREAD_ARG (thread);
3847
3848 oi->t_ls_ack_direct = NULL;
3849
3850 while (listcount (oi->ls_ack_direct.ls_ack))
3851 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3852 oi->ls_ack_direct.dst);
3853
3854 return 0;
3855}
3856
3857void
3858ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3859{
3860 struct ospf_interface *oi = nbr->oi;
3861
3862 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3863 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3864
3865 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3866
3867 if (oi->t_ls_ack_direct == NULL)
3868 oi->t_ls_ack_direct =
3869 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3870}
3871
3872/* Send Link State Acknowledgment delayed. */
3873void
3874ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3875{
3876 struct in_addr dst;
3877
3878 /* Decide destination address. */
3879 /* RFC2328 Section 13.5 On non-broadcast
3880 networks, delayed Link State Acknowledgment packets must be
3881 unicast separately over each adjacency (i.e., neighbor whose
3882 state is >= Exchange). */
3883 if (oi->type == OSPF_IFTYPE_NBMA)
3884 {
3885 struct ospf_neighbor *nbr;
3886 struct route_node *rn;
3887
3888 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3889 if ((nbr = rn->info) != NULL)
3890 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3891 while (listcount (oi->ls_ack))
3892 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3893 return;
3894 }
3895 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3896 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3897 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3898 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3899 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3900 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003901 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3902 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003903 else
3904 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3905
3906 while (listcount (oi->ls_ack))
3907 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3908}