blob: d3f1b5635fe2488d95a9217053771128e489efb3 [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
326
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;
386 unsigned char digest[OSPF_AUTH_MD5_SIZE];
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)))
paul36238142005-10-11 04:12:54 +0000413 auth_key = (const u_int8_t *) "";
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
441
paul4dadc292005-05-06 21:37:42 +0000442static int
paul718e3742002-12-13 20:15:29 +0000443ospf_ls_req_timer (struct thread *thread)
444{
445 struct ospf_neighbor *nbr;
446
447 nbr = THREAD_ARG (thread);
448 nbr->t_ls_req = NULL;
449
450 /* Send Link State Request. */
451 if (ospf_ls_request_count (nbr))
452 ospf_ls_req_send (nbr);
453
454 /* Set Link State Request retransmission timer. */
455 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
456
457 return 0;
458}
459
460void
461ospf_ls_req_event (struct ospf_neighbor *nbr)
462{
463 if (nbr->t_ls_req)
464 {
465 thread_cancel (nbr->t_ls_req);
466 nbr->t_ls_req = NULL;
467 }
468 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
469}
470
471/* Cyclic timer function. Fist registered in ospf_nbr_new () in
472 ospf_neighbor.c */
473int
474ospf_ls_upd_timer (struct thread *thread)
475{
476 struct ospf_neighbor *nbr;
477
478 nbr = THREAD_ARG (thread);
479 nbr->t_ls_upd = NULL;
480
481 /* Send Link State Update. */
482 if (ospf_ls_retransmit_count (nbr) > 0)
483 {
hasso52dc7ee2004-09-23 19:18:23 +0000484 struct list *update;
paul718e3742002-12-13 20:15:29 +0000485 struct ospf_lsdb *lsdb;
486 int i;
paul718e3742002-12-13 20:15:29 +0000487 int retransmit_interval;
488
paul718e3742002-12-13 20:15:29 +0000489 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
490
491 lsdb = &nbr->ls_rxmt;
492 update = list_new ();
493
494 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
495 {
496 struct route_table *table = lsdb->type[i].db;
497 struct route_node *rn;
498
499 for (rn = route_top (table); rn; rn = route_next (rn))
500 {
501 struct ospf_lsa *lsa;
502
503 if ((lsa = rn->info) != NULL)
504 /* Don't retransmit an LSA if we received it within
505 the last RxmtInterval seconds - this is to allow the
506 neighbour a chance to acknowledge the LSA as it may
507 have ben just received before the retransmit timer
508 fired. This is a small tweak to what is in the RFC,
509 but it will cut out out a lot of retransmit traffic
510 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000511 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000512 int2tv (retransmit_interval)) >= 0)
513 listnode_add (update, rn->info);
514 }
515 }
516
517 if (listcount (update) > 0)
518 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
519 list_delete (update);
520 }
521
522 /* Set LS Update retransmission timer. */
523 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
524
525 return 0;
526}
527
528int
529ospf_ls_ack_timer (struct thread *thread)
530{
531 struct ospf_interface *oi;
532
533 oi = THREAD_ARG (thread);
534 oi->t_ls_ack = NULL;
535
536 /* Send Link State Acknowledgment. */
537 if (listcount (oi->ls_ack) > 0)
538 ospf_ls_ack_send_delayed (oi);
539
540 /* Set LS Ack timer. */
541 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
542
543 return 0;
544}
545
paul0bfeca32004-09-24 08:07:54 +0000546#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000547static void
paul6a99f832004-09-27 12:56:30 +0000548ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000549 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000550 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000551{
552#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000553 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000554 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000555 int ret;
paul0bfeca32004-09-24 08:07:54 +0000556
557 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000558 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000559
560 /* we can but try.
561 *
562 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
563 * well as the IP_MF flag, making this all quite pointless.
564 *
565 * However, for a system on which IP_MF is left alone, and ip_id left
566 * alone or else which sets same ip_id for each fragment this might
567 * work, eg linux.
568 *
569 * XXX-TODO: It would be much nicer to have the kernel's use their
570 * existing fragmentation support to do this for us. Bugs/RFEs need to
571 * be raised against the various kernels.
572 */
573
574 /* set More Frag */
575 iph->ip_off |= IP_MF;
576
577 /* ip frag offset is expressed in units of 8byte words */
578 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
579
paul62d8e962004-11-02 20:26:45 +0000580 iovp = &msg->msg_iov[1];
581
paul0bfeca32004-09-24 08:07:54 +0000582 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
583 > maxdatasize )
584 {
585 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000586 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
587 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000588 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000589
paul18b12c32004-10-05 14:38:29 +0000590 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000591
paul6a99f832004-09-27 12:56:30 +0000592 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000593
paul18b12c32004-10-05 14:38:29 +0000594 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000595
596 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000597 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000598 " id %d, off %d, len %d, mtu %u failed with %s",
599 inet_ntoa (iph->ip_dst),
600 iph->ip_id,
601 iph->ip_off,
602 iph->ip_len,
603 mtu,
604 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000605
paul37ccfa32004-10-31 11:24:51 +0000606 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
607 {
ajs2a42e282004-12-08 18:43:03 +0000608 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000609 iph->ip_id, iph->ip_off, iph->ip_len,
610 inet_ntoa (iph->ip_dst));
611 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
612 {
ajs2a42e282004-12-08 18:43:03 +0000613 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000614 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000615 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000616 }
617 }
618
paul0bfeca32004-09-24 08:07:54 +0000619 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000620 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000621 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000622 }
623
624 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000625 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
626 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000627 iph->ip_off &= (~IP_MF);
628}
629#endif /* WANT_OSPF_WRITE_FRAGMENT */
630
ajs5dcbdf82005-03-29 16:13:49 +0000631static int
paul718e3742002-12-13 20:15:29 +0000632ospf_write (struct thread *thread)
633{
paul68980082003-03-25 05:07:42 +0000634 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000635 struct ospf_interface *oi;
636 struct ospf_packet *op;
637 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000638 struct ip iph;
639 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000640 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000641 u_char type;
642 int ret;
643 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000644 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000645#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000646 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000647#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000648 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000649#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000650
paul68980082003-03-25 05:07:42 +0000651 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000652
paul68980082003-03-25 05:07:42 +0000653 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000654 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000655 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000656 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000657
658#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000659 /* seed ipid static with low order bits of time */
660 if (ipid == 0)
661 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000662#endif /* WANT_OSPF_WRITE_FRAGMENT */
663
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000664 /* convenience - max OSPF data per packet,
665 * and reliability - not more data, than our
666 * socket can accept
667 */
668 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
669 sizeof (struct ip);
paul68b73392004-09-12 14:21:37 +0000670
paul718e3742002-12-13 20:15:29 +0000671 /* Get one packet from queue. */
672 op = ospf_fifo_head (oi->obuf);
673 assert (op);
674 assert (op->length >= OSPF_HEADER_SIZE);
675
paul68980082003-03-25 05:07:42 +0000676 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
677 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000678 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
679
paul718e3742002-12-13 20:15:29 +0000680 /* Rewrite the md5 signature & update the seq */
681 ospf_make_md5_digest (oi, op);
682
paul37ccfa32004-10-31 11:24:51 +0000683 /* Retrieve OSPF packet type. */
684 stream_set_getp (op->s, 1);
685 type = stream_getc (op->s);
686
paul68b73392004-09-12 14:21:37 +0000687 /* reset get pointer */
688 stream_set_getp (op->s, 0);
689
690 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000691 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000692
paul718e3742002-12-13 20:15:29 +0000693 sa_dst.sin_family = AF_INET;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000694#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +0000695 sa_dst.sin_len = sizeof(sa_dst);
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000696#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +0000697 sa_dst.sin_addr = op->dst;
698 sa_dst.sin_port = htons (0);
699
700 /* Set DONTROUTE flag if dst is unicast. */
701 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
702 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
703 flags = MSG_DONTROUTE;
704
paul68b73392004-09-12 14:21:37 +0000705 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
706 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000707 if ( sizeof (struct ip)
708 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000709 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
710
paul718e3742002-12-13 20:15:29 +0000711 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000712 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000713 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000714
David BÉRARD0150c9c2010-05-11 10:17:53 +0200715#if defined(__DragonFly__)
716 /*
717 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
718 */
719 iph.ip_len = htons(iph.ip_len);
720#endif
721
paul0bfeca32004-09-24 08:07:54 +0000722#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000723 /* XXX-MT: not thread-safe at all..
724 * XXX: this presumes this is only programme sending OSPF packets
725 * otherwise, no guarantee ipid will be unique
726 */
727 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000728#endif /* WANT_OSPF_WRITE_FRAGMENT */
729
paul718e3742002-12-13 20:15:29 +0000730 iph.ip_off = 0;
731 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
732 iph.ip_ttl = OSPF_VL_IP_TTL;
733 else
734 iph.ip_ttl = OSPF_IP_TTL;
735 iph.ip_p = IPPROTO_OSPFIGP;
736 iph.ip_sum = 0;
737 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
738 iph.ip_dst.s_addr = op->dst.s_addr;
739
740 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000741 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000742 msg.msg_namelen = sizeof (sa_dst);
743 msg.msg_iov = iov;
744 msg.msg_iovlen = 2;
745 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000746 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
747 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000748 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000749
750 /* Sadly we can not rely on kernels to fragment packets because of either
751 * IP_HDRINCL and/or multicast destination being set.
752 */
paul0bfeca32004-09-24 08:07:54 +0000753#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000754 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000755 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
756 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000757#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000758
759 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000760 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000761 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000762 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000763
764 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000765 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000766 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000767 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000768 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000769
paul718e3742002-12-13 20:15:29 +0000770 /* Show debug sending packet. */
771 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
772 {
773 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
774 {
ajs2a42e282004-12-08 18:43:03 +0000775 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000776 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000777 stream_set_getp (op->s, 0);
778 ospf_packet_dump (op->s);
779 }
780
ajs2a42e282004-12-08 18:43:03 +0000781 zlog_debug ("%s sent to [%s] via [%s].",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400782 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
paul718e3742002-12-13 20:15:29 +0000783 IF_NAME (oi));
784
785 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000786 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000787 }
788
789 /* Now delete packet from queue. */
790 ospf_packet_delete (oi);
791
792 if (ospf_fifo_head (oi->obuf) == NULL)
793 {
794 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000795 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000796 }
797
798 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000799 if (!list_isempty (ospf->oi_write_q))
800 ospf->t_write =
801 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000802
803 return 0;
804}
805
806/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000807static void
paul718e3742002-12-13 20:15:29 +0000808ospf_hello (struct ip *iph, struct ospf_header *ospfh,
809 struct stream * s, struct ospf_interface *oi, int size)
810{
811 struct ospf_hello *hello;
812 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000813 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000814 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000815
816 /* increment statistics. */
817 oi->hello_in++;
818
819 hello = (struct ospf_hello *) STREAM_PNT (s);
820
821 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000822 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000823 {
824 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
825 {
ajs2a42e282004-12-08 18:43:03 +0000826 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000827 "dropping.",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400828 LOOKUP (ospf_packet_type_str, ospfh->type),
pauld3241812003-09-29 12:42:39 +0000829 inet_ntoa (iph->ip_src));
830 }
831 return;
832 }
paul718e3742002-12-13 20:15:29 +0000833
paul718e3742002-12-13 20:15:29 +0000834 /* get neighbor prefix. */
835 p.family = AF_INET;
836 p.prefixlen = ip_masklen (hello->network_mask);
837 p.u.prefix4 = iph->ip_src;
838
839 /* Compare network mask. */
840 /* Checking is ignored for Point-to-Point and Virtual link. */
841 if (oi->type != OSPF_IFTYPE_POINTOPOINT
842 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
843 if (oi->address->prefixlen != p.prefixlen)
844 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000845 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
846 inet_ntoa(ospfh->router_id), IF_NAME(oi),
847 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000848 return;
849 }
850
paul718e3742002-12-13 20:15:29 +0000851 /* Compare Router Dead Interval. */
852 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
853 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000854 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
855 "(expected %u, but received %u).",
856 inet_ntoa(ospfh->router_id),
857 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000858 return;
859 }
860
paulf9ad9372005-10-21 00:45:17 +0000861 /* Compare Hello Interval - ignored if fast-hellos are set. */
862 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
863 {
864 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
865 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000866 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
867 "(expected %u, but received %u).",
868 inet_ntoa(ospfh->router_id),
869 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000870 return;
871 }
872 }
873
paul718e3742002-12-13 20:15:29 +0000874 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000875 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000876 inet_ntoa (ospfh->router_id),
877 ospf_options_dump (hello->options));
878
879 /* Compare options. */
880#define REJECT_IF_TBIT_ON 1 /* XXX */
881#ifdef REJECT_IF_TBIT_ON
882 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
883 {
884 /*
885 * This router does not support non-zero TOS.
886 * Drop this Hello packet not to establish neighbor relationship.
887 */
888 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
889 inet_ntoa (ospfh->router_id));
890 return;
891 }
892#endif /* REJECT_IF_TBIT_ON */
893
894#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000895 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000896 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
897 {
898 /*
899 * This router does know the correct usage of O-bit
900 * the bit should be set in DD packet only.
901 */
902 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
903 inet_ntoa (ospfh->router_id));
904#ifdef STRICT_OBIT_USAGE_CHECK
905 return; /* Reject this packet. */
906#else /* STRICT_OBIT_USAGE_CHECK */
907 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
908#endif /* STRICT_OBIT_USAGE_CHECK */
909 }
910#endif /* HAVE_OPAQUE_LSA */
911
912 /* new for NSSA is to ensure that NP is on and E is off */
913
paul718e3742002-12-13 20:15:29 +0000914 if (oi->area->external_routing == OSPF_AREA_NSSA)
915 {
916 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
917 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
918 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
919 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
920 {
921 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
922 return;
923 }
924 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000925 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000926 }
927 else
paul718e3742002-12-13 20:15:29 +0000928 /* The setting of the E-bit found in the Hello Packet's Options
929 field must match this area's ExternalRoutingCapability A
930 mismatch causes processing to stop and the packet to be
931 dropped. The setting of the rest of the bits in the Hello
932 Packet's Options field should be ignored. */
933 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
934 CHECK_FLAG (hello->options, OSPF_OPTION_E))
935 {
ajs3aa8d5f2004-12-11 18:00:06 +0000936 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
937 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000938 return;
939 }
paul718e3742002-12-13 20:15:29 +0000940
pauld3f0d622004-05-05 15:27:15 +0000941 /* get neighbour struct */
942 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
943
944 /* neighbour must be valid, ospf_nbr_get creates if none existed */
945 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000946
947 old_state = nbr->state;
948
949 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000950 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000951
952 /* RFC2328 Section 9.5.1
953 If the router is not eligible to become Designated Router,
954 (snip) It must also send an Hello Packet in reply to an
955 Hello Packet received from any eligible neighbor (other than
956 the current Designated Router and Backup Designated Router). */
957 if (oi->type == OSPF_IFTYPE_NBMA)
958 if (PRIORITY(oi) == 0 && hello->priority > 0
959 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
960 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
961 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
962 OSPF_HELLO_REPLY_DELAY);
963
964 /* on NBMA network type, it happens to receive bidirectional Hello packet
965 without advance 1-Way Received event.
966 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
967 if (oi->type == OSPF_IFTYPE_NBMA &&
968 (old_state == NSM_Down || old_state == NSM_Attempt))
969 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000970 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000971 nbr->priority = hello->priority;
972 nbr->d_router = hello->d_router;
973 nbr->bd_router = hello->bd_router;
974 return;
975 }
976
paul68980082003-03-25 05:07:42 +0000977 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000978 size - OSPF_HELLO_MIN_SIZE))
979 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000980 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000981 nbr->options |= hello->options;
982 }
983 else
984 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000985 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000986 /* Set neighbor information. */
987 nbr->priority = hello->priority;
988 nbr->d_router = hello->d_router;
989 nbr->bd_router = hello->bd_router;
990 return;
991 }
992
993 /* If neighbor itself declares DR and no BDR exists,
994 cause event BackupSeen */
995 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
996 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
997 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
998
999 /* neighbor itself declares BDR. */
1000 if (oi->state == ISM_Waiting &&
1001 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
1002 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
1003
1004 /* had not previously. */
1005 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
1006 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
1007 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
1008 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
1009 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1010
1011 /* had not previously. */
1012 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
1013 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
1014 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
1015 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
1016 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1017
1018 /* Neighbor priority check. */
1019 if (nbr->priority >= 0 && nbr->priority != hello->priority)
1020 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1021
1022 /* Set neighbor information. */
1023 nbr->priority = hello->priority;
1024 nbr->d_router = hello->d_router;
1025 nbr->bd_router = hello->bd_router;
1026}
1027
1028/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +00001029static void
paul718e3742002-12-13 20:15:29 +00001030ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1031 struct ospf_db_desc *dd)
1032{
1033 nbr->last_recv.flags = dd->flags;
1034 nbr->last_recv.options = dd->options;
1035 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1036}
1037
1038/* Process rest of DD packet. */
1039static void
1040ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1041 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1042 u_int16_t size)
1043{
1044 struct ospf_lsa *new, *find;
1045 struct lsa_header *lsah;
1046
paul9985f832005-02-09 15:51:56 +00001047 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001048 for (size -= OSPF_DB_DESC_MIN_SIZE;
1049 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1050 {
1051 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001052 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001053
1054 /* Unknown LS type. */
1055 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1056 {
ajsbec595a2004-11-30 22:38:43 +00001057 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001058 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1059 return;
1060 }
1061
1062#ifdef HAVE_OPAQUE_LSA
1063 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 }
1070#endif /* HAVE_OPAQUE_LSA */
1071
1072 switch (lsah->type)
1073 {
1074 case OSPF_AS_EXTERNAL_LSA:
1075#ifdef HAVE_OPAQUE_LSA
1076 case OSPF_OPAQUE_AS_LSA:
1077#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001078 /* Check for stub area. Reject if AS-External from stub but
1079 allow if from NSSA. */
1080 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001081 {
1082 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1083 lsah->type, inet_ntoa (lsah->id),
1084 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1085 "STUB" : "NSSA");
1086 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1087 return;
1088 }
1089 break;
1090 default:
1091 break;
1092 }
1093
1094 /* Create LS-request object. */
1095 new = ospf_ls_request_new (lsah);
1096
1097 /* Lookup received LSA, then add LS request list. */
1098 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001099
1100 /* ospf_lsa_more_recent is fine with NULL pointers */
1101 switch (ospf_lsa_more_recent (find, new))
1102 {
1103 case -1:
1104 /* Neighbour has a more recent LSA, we must request it */
1105 ospf_ls_request_add (nbr, new);
1106 case 0:
1107 /* If we have a copy of this LSA, it's either less recent
1108 * and we're requesting it from neighbour (the case above), or
1109 * it's as recent and we both have same copy (this case).
1110 *
1111 * In neither of these two cases is there any point in
1112 * describing our copy of the LSA to the neighbour in a
1113 * DB-Summary packet, if we're still intending to do so.
1114 *
1115 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1116 * backward compatible optimisation to OSPF DB Exchange /
1117 * DB Description process implemented here.
1118 */
1119 if (find)
1120 ospf_lsdb_delete (&nbr->db_sum, find);
1121 ospf_lsa_discard (new);
1122 break;
1123 default:
1124 /* We have the more recent copy, nothing specific to do:
1125 * - no need to request neighbours stale copy
1126 * - must leave DB summary list copy alone
1127 */
1128 if (IS_DEBUG_OSPF_EVENT)
1129 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1130 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1131 ospf_lsa_discard (new);
1132 }
paul718e3742002-12-13 20:15:29 +00001133 }
1134
1135 /* Master */
1136 if (IS_SET_DD_MS (nbr->dd_flags))
1137 {
1138 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001139
1140 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001141 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1142 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1143 else
paul718e3742002-12-13 20:15:29 +00001144 ospf_db_desc_send (nbr);
1145 }
1146 /* Slave */
1147 else
1148 {
1149 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1150
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001151 /* Send DD packet in reply.
1152 *
1153 * Must be done to acknowledge the Master's DD, regardless of
1154 * whether we have more LSAs ourselves to describe.
1155 *
1156 * This function will clear the 'More' bit, if after this DD
1157 * we have no more LSAs to describe to the master..
1158 */
paul718e3742002-12-13 20:15:29 +00001159 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001160
1161 /* Slave can raise ExchangeDone now, if master is also done */
1162 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1163 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001164 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001165
paul718e3742002-12-13 20:15:29 +00001166 /* Save received neighbor values from DD. */
1167 ospf_db_desc_save_current (nbr, dd);
1168}
1169
paul4dadc292005-05-06 21:37:42 +00001170static int
paul718e3742002-12-13 20:15:29 +00001171ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1172{
1173 /* Is DD duplicated? */
1174 if (dd->options == nbr->last_recv.options &&
1175 dd->flags == nbr->last_recv.flags &&
1176 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1177 return 1;
1178
1179 return 0;
1180}
1181
1182/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001183static void
paul718e3742002-12-13 20:15:29 +00001184ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1185 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1186{
1187 struct ospf_db_desc *dd;
1188 struct ospf_neighbor *nbr;
1189
1190 /* Increment statistics. */
1191 oi->db_desc_in++;
1192
1193 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001194
pauld3f0d622004-05-05 15:27:15 +00001195 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001196 if (nbr == NULL)
1197 {
1198 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1199 inet_ntoa (ospfh->router_id));
1200 return;
1201 }
1202
1203 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001204 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1205 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001206 {
ajs3aa8d5f2004-12-11 18:00:06 +00001207 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1208 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1209 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001210 return;
1211 }
1212
pauld363df22003-06-19 00:26:34 +00001213 /*
1214 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1215 * required. In fact at least JunOS sends DD packets with P bit clear.
1216 * Until proper solution is developped, this hack should help.
1217 *
1218 * Update: According to the RFCs, N bit is specified /only/ for Hello
1219 * options, unfortunately its use in DD options is not specified. Hence some
1220 * implementations follow E-bit semantics and set it in DD options, and some
1221 * treat it as unspecified and hence follow the directive "default for
1222 * options is clear", ie unset.
1223 *
1224 * Reset the flag, as ospfd follows E-bit semantics.
1225 */
1226 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1227 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1228 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1229 {
1230 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001231 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001232 inet_ntoa (nbr->router_id) );
1233 SET_FLAG (dd->options, OSPF_OPTION_NP);
1234 }
pauld363df22003-06-19 00:26:34 +00001235
paul718e3742002-12-13 20:15:29 +00001236#ifdef REJECT_IF_TBIT_ON
1237 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1238 {
1239 /*
1240 * In Hello protocol, optional capability must have checked
1241 * to prevent this T-bit enabled router be my neighbor.
1242 */
1243 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1244 return;
1245 }
1246#endif /* REJECT_IF_TBIT_ON */
1247
1248#ifdef HAVE_OPAQUE_LSA
1249 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001250 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001251 {
1252 /*
1253 * This node is not configured to handle O-bit, for now.
1254 * Clear it to ignore unsupported capability proposed by neighbor.
1255 */
1256 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1257 }
1258#endif /* HAVE_OPAQUE_LSA */
1259
Paul Jakma57c5c652010-01-07 06:12:53 +00001260 /* Add event to thread. */
1261 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1262
paul718e3742002-12-13 20:15:29 +00001263 /* Process DD packet by neighbor status. */
1264 switch (nbr->state)
1265 {
1266 case NSM_Down:
1267 case NSM_Attempt:
1268 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001269 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001270 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001271 LOOKUP (ospf_nsm_state_msg, nbr->state));
1272 break;
1273 case NSM_Init:
1274 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1275 /* If the new state is ExStart, the processing of the current
1276 packet should then continue in this new state by falling
1277 through to case ExStart below. */
1278 if (nbr->state != NSM_ExStart)
1279 break;
1280 case NSM_ExStart:
1281 /* Initial DBD */
1282 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1283 (size == OSPF_DB_DESC_MIN_SIZE))
1284 {
paul68980082003-03-25 05:07:42 +00001285 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001286 {
1287 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001288 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001289 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001290 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001291
1292 /* Reset I/MS */
1293 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001294 }
1295 else
1296 {
1297 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001298 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001299 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001300 break;
1301 }
1302 }
1303 /* Ack from the Slave */
1304 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1305 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001306 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001307 {
ajs17eaa722004-12-29 21:04:48 +00001308 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001309 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001310 /* Reset I, leaving MS */
1311 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001312 }
1313 else
1314 {
ajs3aa8d5f2004-12-11 18:00:06 +00001315 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1316 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001317 break;
1318 }
1319
1320 /* This is where the real Options are saved */
1321 nbr->options = dd->options;
1322
1323#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001324 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001325 {
1326 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001327 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001328 inet_ntoa (nbr->router_id),
1329 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1330
1331 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1332 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1333 {
paul6d452762005-11-03 11:15:44 +00001334 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1335 "Opaque-LSAs cannot be reliably advertised "
1336 "in this network.",
1337 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001338 /* This situation is undesirable, but not a real error. */
1339 }
1340 }
1341#endif /* HAVE_OPAQUE_LSA */
1342
1343 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1344
1345 /* continue processing rest of packet. */
1346 ospf_db_desc_proc (s, oi, nbr, dd, size);
1347 break;
1348 case NSM_Exchange:
1349 if (ospf_db_desc_is_dup (dd, nbr))
1350 {
1351 if (IS_SET_DD_MS (nbr->dd_flags))
1352 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001353 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001354 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001355 else
1356 /* Slave: cause to retransmit the last Database Description. */
1357 {
paul6d452762005-11-03 11:15:44 +00001358 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001359 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001360 ospf_db_desc_resend (nbr);
1361 }
1362 break;
1363 }
1364
1365 /* Otherwise DD packet should be checked. */
1366 /* Check Master/Slave bit mismatch */
1367 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1368 {
ajs3aa8d5f2004-12-11 18:00:06 +00001369 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1370 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001371 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1372 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001373 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001374 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001375 break;
1376 }
1377
1378 /* Check initialize bit is set. */
1379 if (IS_SET_DD_I (dd->flags))
1380 {
paul6d452762005-11-03 11:15:44 +00001381 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001382 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001383 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1384 break;
1385 }
1386
1387 /* Check DD Options. */
1388 if (dd->options != nbr->options)
1389 {
1390#ifdef ORIGINAL_CODING
1391 /* Save the new options for debugging */
1392 nbr->options = dd->options;
1393#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001394 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1395 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001396 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1397 break;
1398 }
1399
1400 /* Check DD sequence number. */
1401 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1402 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1403 (!IS_SET_DD_MS (nbr->dd_flags) &&
1404 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1405 {
ajs3aa8d5f2004-12-11 18:00:06 +00001406 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1407 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001408 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1409 break;
1410 }
1411
1412 /* Continue processing rest of packet. */
1413 ospf_db_desc_proc (s, oi, nbr, dd, size);
1414 break;
1415 case NSM_Loading:
1416 case NSM_Full:
1417 if (ospf_db_desc_is_dup (dd, nbr))
1418 {
1419 if (IS_SET_DD_MS (nbr->dd_flags))
1420 {
1421 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001422 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1423 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001424 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001425 break;
1426 }
1427 else
1428 {
1429 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001430 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001431 t = tv_sub (now, nbr->last_send_ts);
1432 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1433 {
1434 /* In states Loading and Full the slave must resend
1435 its last Database Description packet in response to
1436 duplicate Database Description packets received
1437 from the master. For this reason the slave must
1438 wait RouterDeadInterval seconds before freeing the
1439 last Database Description packet. Reception of a
1440 Database Description packet from the master after
1441 this interval will generate a SeqNumberMismatch
1442 neighbor event. RFC2328 Section 10.8 */
1443 ospf_db_desc_resend (nbr);
1444 break;
1445 }
1446 }
1447 }
1448
1449 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1450 break;
1451 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001452 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1453 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001454 break;
1455 }
1456}
1457
1458#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1459
1460/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001461static void
paul718e3742002-12-13 20:15:29 +00001462ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1463 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1464{
1465 struct ospf_neighbor *nbr;
1466 u_int32_t ls_type;
1467 struct in_addr ls_id;
1468 struct in_addr adv_router;
1469 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001470 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001471 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001472
1473 /* Increment statistics. */
1474 oi->ls_req_in++;
1475
pauld3f0d622004-05-05 15:27:15 +00001476 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001477 if (nbr == NULL)
1478 {
1479 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1480 inet_ntoa (ospfh->router_id));
1481 return;
1482 }
1483
Paul Jakma57c5c652010-01-07 06:12:53 +00001484 /* Add event to thread. */
1485 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1486
paul718e3742002-12-13 20:15:29 +00001487 /* Neighbor State should be Exchange or later. */
1488 if (nbr->state != NSM_Exchange &&
1489 nbr->state != NSM_Loading &&
1490 nbr->state != NSM_Full)
1491 {
ajsbec595a2004-11-30 22:38:43 +00001492 zlog_warn ("Link State Request received from %s: "
1493 "Neighbor state is %s, packet discarded.",
1494 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001495 LOOKUP (ospf_nsm_state_msg, nbr->state));
1496 return;
1497 }
1498
1499 /* Send Link State Update for ALL requested LSAs. */
1500 ls_upd = list_new ();
1501 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1502
1503 while (size >= OSPF_LSA_KEY_SIZE)
1504 {
1505 /* Get one slice of Link State Request. */
1506 ls_type = stream_getl (s);
1507 ls_id.s_addr = stream_get_ipv4 (s);
1508 adv_router.s_addr = stream_get_ipv4 (s);
1509
1510 /* Verify LSA type. */
1511 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1512 {
1513 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1514 list_delete (ls_upd);
1515 return;
1516 }
1517
1518 /* Search proper LSA in LSDB. */
1519 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1520 if (find == NULL)
1521 {
1522 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1523 list_delete (ls_upd);
1524 return;
1525 }
1526
gdt86f1fd92005-01-10 14:20:43 +00001527 /* Packet overflows MTU size, send immediately. */
1528 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001529 {
1530 if (oi->type == OSPF_IFTYPE_NBMA)
1531 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1532 else
1533 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1534
1535 /* Only remove list contents. Keep ls_upd. */
1536 list_delete_all_node (ls_upd);
1537
1538 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1539 }
1540
1541 /* Append LSA to update list. */
1542 listnode_add (ls_upd, find);
1543 length += ntohs (find->data->length);
1544
1545 size -= OSPF_LSA_KEY_SIZE;
1546 }
1547
1548 /* Send rest of Link State Update. */
1549 if (listcount (ls_upd) > 0)
1550 {
1551 if (oi->type == OSPF_IFTYPE_NBMA)
1552 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1553 else
1554 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1555
1556 list_delete (ls_upd);
1557 }
1558 else
1559 list_free (ls_upd);
1560}
1561
1562/* Get the list of LSAs from Link State Update packet.
1563 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001564static struct list *
paul718e3742002-12-13 20:15:29 +00001565ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1566 struct ospf_interface *oi, size_t size)
1567{
1568 u_int16_t count, sum;
1569 u_int32_t length;
1570 struct lsa_header *lsah;
1571 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001572 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001573
1574 lsas = list_new ();
1575
1576 count = stream_getl (s);
1577 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1578
1579 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001580 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001581 {
1582 lsah = (struct lsa_header *) STREAM_PNT (s);
1583 length = ntohs (lsah->length);
1584
1585 if (length > size)
1586 {
1587 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1588 break;
1589 }
1590
1591 /* Validate the LSA's LS checksum. */
1592 sum = lsah->checksum;
JR Riversd8a4e422012-09-13 17:17:36 +00001593 if (! ospf_lsa_checksum_valid (lsah))
paul718e3742002-12-13 20:15:29 +00001594 {
Jaroslav Fojtik223da1a2011-12-11 18:22:16 +04001595 /* (bug #685) more details in a one-line message make it possible
1596 * to identify problem source on the one hand and to have a better
1597 * chance to compress repeated messages in syslog on the other */
1598 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1599 sum, lsah->checksum, inet_ntoa (lsah->id),
1600 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1601 inet_ntoa (lsah->adv_router));
paul718e3742002-12-13 20:15:29 +00001602 continue;
1603 }
1604
1605 /* Examine the LSA's LS type. */
1606 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1607 {
1608 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1609 continue;
1610 }
1611
1612 /*
1613 * What if the received LSA's age is greater than MaxAge?
1614 * Treat it as a MaxAge case -- endo.
1615 */
1616 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1617 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1618
1619#ifdef HAVE_OPAQUE_LSA
1620 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1621 {
1622#ifdef STRICT_OBIT_USAGE_CHECK
1623 if ((IS_OPAQUE_LSA(lsah->type) &&
1624 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1625 || (! IS_OPAQUE_LSA(lsah->type) &&
1626 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1627 {
1628 /*
1629 * This neighbor must know the exact usage of O-bit;
1630 * the bit will be set in Type-9,10,11 LSAs only.
1631 */
1632 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1633 continue;
1634 }
1635#endif /* STRICT_OBIT_USAGE_CHECK */
1636
1637 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1638 if (lsah->type == OSPF_OPAQUE_AS_LSA
1639 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1640 {
1641 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001642 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 +00001643 continue;
1644 }
1645 }
1646 else if (IS_OPAQUE_LSA(lsah->type))
1647 {
1648 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1649 continue;
1650 }
1651#endif /* HAVE_OPAQUE_LSA */
1652
1653 /* Create OSPF LSA instance. */
1654 lsa = ospf_lsa_new ();
1655
1656 /* We may wish to put some error checking if type NSSA comes in
1657 and area not in NSSA mode */
1658 switch (lsah->type)
1659 {
1660 case OSPF_AS_EXTERNAL_LSA:
1661#ifdef HAVE_OPAQUE_LSA
1662 case OSPF_OPAQUE_AS_LSA:
Christian Franke58952492013-02-20 10:00:53 +00001663#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001664 lsa->area = NULL;
1665 break;
Christian Franke58952492013-02-20 10:00:53 +00001666#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001667 case OSPF_OPAQUE_LINK_LSA:
1668 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1669 /* Fallthrough */
1670#endif /* HAVE_OPAQUE_LSA */
1671 default:
1672 lsa->area = oi->area;
1673 break;
1674 }
1675
1676 lsa->data = ospf_lsa_data_new (length);
1677 memcpy (lsa->data, lsah, length);
1678
1679 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001680 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001681 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1682 listnode_add (lsas, lsa);
1683 }
1684
1685 return lsas;
1686}
1687
1688/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001689static void
hasso52dc7ee2004-09-23 19:18:23 +00001690ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001691{
paul1eb8ef22005-04-07 07:30:20 +00001692 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001693 struct ospf_lsa *lsa;
1694
paul1eb8ef22005-04-07 07:30:20 +00001695 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1696 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001697
1698 list_delete (lsas);
1699}
1700
1701/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001702static void
paul718e3742002-12-13 20:15:29 +00001703ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1704 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1705{
1706 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001707 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001708 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001709 struct ospf_lsa *lsa = NULL;
1710 /* unsigned long ls_req_found = 0; */
1711
1712 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1713
1714 /* Increment statistics. */
1715 oi->ls_upd_in++;
1716
1717 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001718 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001719 if (nbr == NULL)
1720 {
1721 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1722 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1723 return;
1724 }
1725
Paul Jakma57c5c652010-01-07 06:12:53 +00001726 /* Add event to thread. */
1727 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1728
paul718e3742002-12-13 20:15:29 +00001729 /* Check neighbor state. */
1730 if (nbr->state < NSM_Exchange)
1731 {
ajs3aa8d5f2004-12-11 18:00:06 +00001732 zlog_warn ("Link State Update: "
1733 "Neighbor[%s] state %s is less than Exchange",
1734 inet_ntoa (ospfh->router_id),
1735 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001736 return;
1737 }
1738
1739 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1740 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1741 * of section 13.
1742 */
1743 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1744
1745#ifdef HAVE_OPAQUE_LSA
1746 /*
paul718e3742002-12-13 20:15:29 +00001747 * If self-originated Opaque-LSAs that have flooded before restart
1748 * are contained in the received LSUpd message, corresponding LSReq
1749 * messages to be sent may have to be modified.
1750 * To eliminate possible race conditions such that flushing and normal
1751 * updating for the same LSA would take place alternately, this trick
1752 * must be done before entering to the loop below.
1753 */
paul69310a62005-05-11 18:09:59 +00001754 /* XXX: Why is this Opaque specific? Either our core code is deficient
1755 * and this should be fixed generally, or Opaque is inventing strawman
1756 * problems */
paul718e3742002-12-13 20:15:29 +00001757 ospf_opaque_adjust_lsreq (nbr, lsas);
1758#endif /* HAVE_OPAQUE_LSA */
1759
1760#define DISCARD_LSA(L,N) {\
1761 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001762 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
paul718e3742002-12-13 20:15:29 +00001763 ospf_lsa_discard (L); \
1764 continue; }
1765
Andrew Certainf92c57f2012-12-04 13:29:21 -08001766 /* Process each LSA received in the one packet.
1767 *
1768 * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
Andrew Certain0798cee2012-12-04 13:43:42 -08001769 * text below are from the steps in RFC 2328, Section 13.
Andrew Certainf92c57f2012-12-04 13:29:21 -08001770 */
paul1eb8ef22005-04-07 07:30:20 +00001771 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001772 {
1773 struct ospf_lsa *ls_ret, *current;
1774 int ret = 1;
1775
paul718e3742002-12-13 20:15:29 +00001776 if (IS_DEBUG_OSPF_NSSA)
1777 {
1778 char buf1[INET_ADDRSTRLEN];
1779 char buf2[INET_ADDRSTRLEN];
1780 char buf3[INET_ADDRSTRLEN];
1781
ajs2a42e282004-12-08 18:43:03 +00001782 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001783 lsa->data->type,
1784 inet_ntop (AF_INET, &ospfh->router_id,
1785 buf1, INET_ADDRSTRLEN),
1786 inet_ntop (AF_INET, &lsa->data->id,
1787 buf2, INET_ADDRSTRLEN),
1788 inet_ntop (AF_INET, &lsa->data->adv_router,
1789 buf3, INET_ADDRSTRLEN));
1790 }
paul718e3742002-12-13 20:15:29 +00001791
1792 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1793
Andrew Certainf92c57f2012-12-04 13:29:21 -08001794 /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
paul718e3742002-12-13 20:15:29 +00001795
Andrew Certainf92c57f2012-12-04 13:29:21 -08001796 /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
paul718e3742002-12-13 20:15:29 +00001797
Andrew Certainf92c57f2012-12-04 13:29:21 -08001798 /* (3) Do not take in AS External LSAs if we are a stub or NSSA. */
paul718e3742002-12-13 20:15:29 +00001799
1800 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1801
1802 /* Do take in Type-7's if we are an NSSA */
1803
1804 /* If we are also an ABR, later translate them to a Type-5 packet */
1805
1806 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1807 translate them to a separate Type-5 packet. */
1808
1809 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1810 /* Reject from STUB or NSSA */
1811 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1812 {
paul718e3742002-12-13 20:15:29 +00001813 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001814 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001815 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001816 }
1817
paul718e3742002-12-13 20:15:29 +00001818 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1819 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1820 {
paul718e3742002-12-13 20:15:29 +00001821 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001822 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001823 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001824 }
paul718e3742002-12-13 20:15:29 +00001825
1826 /* Find the LSA in the current database. */
1827
1828 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1829
Andrew Certainf92c57f2012-12-04 13:29:21 -08001830 /* (4) If the LSA's LS age is equal to MaxAge, and there is currently
paul718e3742002-12-13 20:15:29 +00001831 no instance of the LSA in the router's link state database,
1832 and none of router's neighbors are in states Exchange or Loading,
Andrew Certainf92c57f2012-12-04 13:29:21 -08001833 then take the following actions: */
paul718e3742002-12-13 20:15:29 +00001834
1835 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001836 (ospf_nbr_count (oi, NSM_Exchange) +
1837 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001838 {
Andrew Certainf92c57f2012-12-04 13:29:21 -08001839 /* (4a) Response Link State Acknowledgment. */
paul718e3742002-12-13 20:15:29 +00001840 ospf_ls_ack_send (nbr, lsa);
1841
Andrew Certainf92c57f2012-12-04 13:29:21 -08001842 /* (4b) Discard LSA. */
Ayan Banerjeefaf98752012-12-04 10:49:12 -08001843 if (IS_DEBUG_OSPF (lsa, LSA))
1844 {
1845 zlog_debug ("Link State Update[%s]: LS age is equal to MaxAge.",
1846 dump_lsa_key(lsa));
1847 }
paul718e3742002-12-13 20:15:29 +00001848 DISCARD_LSA (lsa, 3);
1849 }
1850
1851#ifdef HAVE_OPAQUE_LSA
1852 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001853 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001854 {
1855 /*
1856 * Even if initial flushing seems to be completed, there might
1857 * be a case that self-originated LSA with MaxAge still remain
1858 * in the routing domain.
1859 * Just send an LSAck message to cease retransmission.
1860 */
1861 if (IS_LSA_MAXAGE (lsa))
1862 {
1863 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1864 ospf_ls_ack_send (nbr, lsa);
1865 ospf_lsa_discard (lsa);
1866
1867 if (current != NULL && ! IS_LSA_MAXAGE (current))
1868 ospf_opaque_lsa_refresh_schedule (current);
1869 continue;
1870 }
1871
1872 /*
1873 * If an instance of self-originated Opaque-LSA is not found
1874 * in the LSDB, there are some possible cases here.
1875 *
1876 * 1) This node lost opaque-capability after restart.
1877 * 2) Else, a part of opaque-type is no more supported.
1878 * 3) Else, a part of opaque-id is no more supported.
1879 *
1880 * Anyway, it is still this node's responsibility to flush it.
1881 * Otherwise, the LSA instance remains in the routing domain
1882 * until its age reaches to MaxAge.
1883 */
paul69310a62005-05-11 18:09:59 +00001884 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001885 if (current == NULL)
1886 {
1887 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001888 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1889 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001890
1891 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001892
1893 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1894 ospf_ls_ack_send (nbr, lsa);
1895
paul718e3742002-12-13 20:15:29 +00001896 continue;
1897 }
1898 }
1899#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001900
hassocb05eb22004-02-11 21:10:19 +00001901 /* It might be happen that received LSA is self-originated network LSA, but
Andrew Certainf92c57f2012-12-04 13:29:21 -08001902 * router ID is changed. So, we should check if LSA is a network-LSA whose
hassocb05eb22004-02-11 21:10:19 +00001903 * Link State ID is one of the router's own IP interface addresses but whose
1904 * Advertising Router is not equal to the router's own Router ID
1905 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1906 */
1907
1908 if(lsa->data->type == OSPF_NETWORK_LSA)
1909 {
paul1eb8ef22005-04-07 07:30:20 +00001910 struct listnode *oinode, *oinnode;
1911 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001912 int Flag = 0;
1913
paul1eb8ef22005-04-07 07:30:20 +00001914 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001915 {
hassocb05eb22004-02-11 21:10:19 +00001916 if(out_if == NULL)
1917 break;
1918
1919 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1920 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1921 {
1922 if(out_if->network_lsa_self)
1923 {
1924 ospf_lsa_flush_area(lsa,out_if->area);
1925 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001926 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001927 lsa, (int) lsa->data->type);
1928 ospf_lsa_discard (lsa);
1929 Flag = 1;
1930 }
1931 break;
1932 }
1933 }
1934 if(Flag)
1935 continue;
1936 }
paul718e3742002-12-13 20:15:29 +00001937
1938 /* (5) Find the instance of this LSA that is currently contained
1939 in the router's link state database. If there is no
1940 database copy, or the received LSA is more recent than
Andrew Certainf92c57f2012-12-04 13:29:21 -08001941 the database copy the following steps must be performed.
1942 (The sub steps from RFC 2328 section 13 step (5) will be performed in
1943 ospf_flood() ) */
paul718e3742002-12-13 20:15:29 +00001944
1945 if (current == NULL ||
1946 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1947 {
1948 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001949 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001950 DISCARD_LSA (lsa, 4);
1951 continue;
1952 }
1953
1954 /* (6) Else, If there is an instance of the LSA on the sending
1955 neighbor's Link state request list, an error has occurred in
1956 the Database Exchange process. In this case, restart the
1957 Database Exchange process by generating the neighbor event
1958 BadLSReq for the sending neighbor and stop processing the
1959 Link State Update packet. */
1960
1961 if (ospf_ls_request_lookup (nbr, lsa))
1962 {
1963 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001964 zlog_warn("LSA[%s] instance exists on Link state request list",
1965 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001966
1967 /* Clean list of LSAs. */
1968 ospf_upd_list_clean (lsas);
1969 /* this lsa is not on lsas list already. */
1970 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001971 return;
1972 }
1973
1974 /* If the received LSA is the same instance as the database copy
1975 (i.e., neither one is more recent) the following two steps
1976 should be performed: */
1977
1978 if (ret == 0)
1979 {
1980 /* If the LSA is listed in the Link state retransmission list
1981 for the receiving adjacency, the router itself is expecting
1982 an acknowledgment for this LSA. The router should treat the
1983 received LSA as an acknowledgment by removing the LSA from
1984 the Link state retransmission list. This is termed an
1985 "implied acknowledgment". */
1986
1987 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1988
1989 if (ls_ret != NULL)
1990 {
1991 ospf_ls_retransmit_delete (nbr, ls_ret);
1992
1993 /* Delayed acknowledgment sent if advertisement received
1994 from Designated Router, otherwise do nothing. */
1995 if (oi->state == ISM_Backup)
1996 if (NBR_IS_DR (nbr))
1997 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1998
1999 DISCARD_LSA (lsa, 5);
2000 }
2001 else
2002 /* Acknowledge the receipt of the LSA by sending a
2003 Link State Acknowledgment packet back out the receiving
2004 interface. */
2005 {
2006 ospf_ls_ack_send (nbr, lsa);
2007 DISCARD_LSA (lsa, 6);
2008 }
2009 }
2010
2011 /* The database copy is more recent. If the database copy
2012 has LS age equal to MaxAge and LS sequence number equal to
2013 MaxSequenceNumber, simply discard the received LSA without
2014 acknowledging it. (In this case, the LSA's LS sequence number is
2015 wrapping, and the MaxSequenceNumber LSA must be completely
2016 flushed before any new LSA instance can be introduced). */
2017
2018 else if (ret > 0) /* Database copy is more recent */
2019 {
2020 if (IS_LSA_MAXAGE (current) &&
2021 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
2022 {
2023 DISCARD_LSA (lsa, 7);
2024 }
2025 /* Otherwise, as long as the database copy has not been sent in a
2026 Link State Update within the last MinLSArrival seconds, send the
2027 database copy back to the sending neighbor, encapsulated within
2028 a Link State Update Packet. The Link State Update Packet should
2029 be sent directly to the neighbor. In so doing, do not put the
2030 database copy of the LSA on the neighbor's link state
2031 retransmission list, and do not acknowledge the received (less
2032 recent) LSA instance. */
2033 else
2034 {
2035 struct timeval now;
2036
Paul Jakma2518efd2006-08-27 06:49:29 +00002037 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00002038
2039 if (tv_cmp (tv_sub (now, current->tv_orig),
Paul Jakma2c9f8e32010-01-11 16:22:12 +00002040 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
paul718e3742002-12-13 20:15:29 +00002041 /* Trap NSSA type later.*/
2042 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2043 DISCARD_LSA (lsa, 8);
2044 }
2045 }
2046 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002047#undef DISCARD_LSA
2048
paul718e3742002-12-13 20:15:29 +00002049 assert (listcount (lsas) == 0);
2050 list_delete (lsas);
2051}
2052
2053/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002054static void
paul718e3742002-12-13 20:15:29 +00002055ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2056 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2057{
2058 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002059
paul718e3742002-12-13 20:15:29 +00002060 /* increment statistics. */
2061 oi->ls_ack_in++;
2062
pauld3f0d622004-05-05 15:27:15 +00002063 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002064 if (nbr == NULL)
2065 {
2066 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2067 inet_ntoa (ospfh->router_id));
2068 return;
2069 }
2070
Paul Jakma57c5c652010-01-07 06:12:53 +00002071 /* Add event to thread. */
2072 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2073
paul718e3742002-12-13 20:15:29 +00002074 if (nbr->state < NSM_Exchange)
2075 {
ajs3aa8d5f2004-12-11 18:00:06 +00002076 zlog_warn ("Link State Acknowledgment: "
2077 "Neighbor[%s] state %s is less than Exchange",
2078 inet_ntoa (ospfh->router_id),
2079 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002080 return;
2081 }
paul69310a62005-05-11 18:09:59 +00002082
paul718e3742002-12-13 20:15:29 +00002083 while (size >= OSPF_LSA_HEADER_SIZE)
2084 {
2085 struct ospf_lsa *lsa, *lsr;
2086
2087 lsa = ospf_lsa_new ();
2088 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2089
2090 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2091 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002092 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002093
2094 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2095 {
2096 lsa->data = NULL;
2097 ospf_lsa_discard (lsa);
2098 continue;
2099 }
2100
2101 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2102
2103 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2104 {
2105#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002106 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002107 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002108#endif /* HAVE_OPAQUE_LSA */
2109
2110 ospf_ls_retransmit_delete (nbr, lsr);
2111 }
2112
2113 lsa->data = NULL;
2114 ospf_lsa_discard (lsa);
2115 }
2116
paul718e3742002-12-13 20:15:29 +00002117 return;
paul718e3742002-12-13 20:15:29 +00002118}
2119
ajs038163f2005-02-17 19:55:59 +00002120static struct stream *
ajs5c333492005-02-23 15:43:01 +00002121ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002122{
2123 int ret;
ajs5c333492005-02-23 15:43:01 +00002124 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002125 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002126 unsigned int ifindex = 0;
2127 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002128 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002129 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002130 struct msghdr msgh;
2131
paul68defd62004-09-27 07:27:13 +00002132 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002133 msgh.msg_iov = &iov;
2134 msgh.msg_iovlen = 1;
2135 msgh.msg_control = (caddr_t) buff;
2136 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002137
ajs5c333492005-02-23 15:43:01 +00002138 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2139 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002140 {
ajs5c333492005-02-23 15:43:01 +00002141 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2142 return NULL;
2143 }
paul69310a62005-05-11 18:09:59 +00002144 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002145 {
2146 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2147 "(ip header size is %u)",
2148 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002149 return NULL;
2150 }
paul18b12c32004-10-05 14:38:29 +00002151
ajs5c333492005-02-23 15:43:01 +00002152 /* Note that there should not be alignment problems with this assignment
2153 because this is at the beginning of the stream data buffer. */
2154 iph = (struct ip *) STREAM_DATA(ibuf);
2155 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002156
ajs5c333492005-02-23 15:43:01 +00002157 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002158
Dmitrij Tejblumde5ccb92011-12-12 20:30:10 +04002159#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
paul718e3742002-12-13 20:15:29 +00002160 /*
2161 * Kernel network code touches incoming IP header parameters,
2162 * before protocol specific processing.
2163 *
2164 * 1) Convert byteorder to host representation.
2165 * --> ip_len, ip_id, ip_off
2166 *
2167 * 2) Adjust ip_len to strip IP header size!
2168 * --> If user process receives entire IP packet via RAW
2169 * socket, it must consider adding IP header size to
2170 * the "ip_len" field of "ip" structure.
2171 *
2172 * For more details, see <netinet/ip_input.c>.
2173 */
ajs5c333492005-02-23 15:43:01 +00002174 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002175#endif
2176
David BÉRARD0150c9c2010-05-11 10:17:53 +02002177#if defined(__DragonFly__)
2178 /*
2179 * in DragonFly's raw socket, ip_len/ip_off are read
2180 * in network byte order.
2181 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2182 */
2183 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2184#endif
2185
paul863082d2004-08-19 04:43:43 +00002186 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002187
2188 *ifp = if_lookup_by_index (ifindex);
2189
2190 if (ret != ip_len)
2191 {
ajs5c333492005-02-23 15:43:01 +00002192 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2193 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002194 return NULL;
2195 }
2196
2197 return ibuf;
2198}
2199
paul4dadc292005-05-06 21:37:42 +00002200static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002201ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002202 struct ip *iph, struct ospf_header *ospfh)
2203{
2204 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002205 struct ospf_vl_data *vl_data;
2206 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002207 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002208
2209 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2210 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002211 return NULL;
paul718e3742002-12-13 20:15:29 +00002212
pauld3f0d622004-05-05 15:27:15 +00002213 /* look for local OSPF interface matching the destination
2214 * to determine Area ID. We presume therefore the destination address
2215 * is unique, or at least (for "unnumbered" links), not used in other
2216 * areas
2217 */
2218 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2219 iph->ip_dst)) == NULL)
2220 return NULL;
paul718e3742002-12-13 20:15:29 +00002221
paul1eb8ef22005-04-07 07:30:20 +00002222 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002223 {
paul020709f2003-04-04 02:44:16 +00002224 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002225 if (!vl_area)
2226 continue;
2227
2228 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2229 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2230 {
2231 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002232 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002233 IF_NAME (vl_data->vl_oi));
2234 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2235 {
2236 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002237 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002238 return NULL;
2239 }
2240
2241 return vl_data->vl_oi;
2242 }
2243 }
2244
2245 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002246 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002247
pauld3f0d622004-05-05 15:27:15 +00002248 return NULL;
paul718e3742002-12-13 20:15:29 +00002249}
2250
Paul Jakmaf63f06d2011-04-08 12:44:43 +01002251static int
paul718e3742002-12-13 20:15:29 +00002252ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2253{
2254 /* Check match the Area ID of the receiving interface. */
2255 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2256 return 1;
2257
2258 return 0;
2259}
2260
2261/* Unbound socket will accept any Raw IP packets if proto is matched.
2262 To prevent it, compare src IP address and i/f address with masking
2263 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002264static int
paul718e3742002-12-13 20:15:29 +00002265ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2266{
2267 struct in_addr mask, me, him;
2268
2269 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2270 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2271 return 1;
2272
2273 masklen2ip (oi->address->prefixlen, &mask);
2274
2275 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2276 him.s_addr = ip_src.s_addr & mask.s_addr;
2277
2278 if (IPV4_ADDR_SAME (&me, &him))
2279 return 1;
2280
2281 return 0;
2282}
2283
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002284/* Return 1, if the packet is properly authenticated and checksummed,
2285 0 otherwise. In particular, check that AuType header field is valid and
2286 matches the locally configured AuType, and that D.5 requirements are met. */
paul4dadc292005-05-06 21:37:42 +00002287static int
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002288ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +00002289{
paul718e3742002-12-13 20:15:29 +00002290 struct crypt_key *ck;
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002291 u_int16_t iface_auth_type;
2292 u_int16_t pkt_auth_type = ntohs (ospfh->auth_type);
paul718e3742002-12-13 20:15:29 +00002293
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002294 switch (pkt_auth_type)
2295 {
2296 case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
2297 if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))
paul718e3742002-12-13 20:15:29 +00002298 {
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002299 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2300 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null",
2301 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2302 return 0;
paul718e3742002-12-13 20:15:29 +00002303 }
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002304 if (! ospf_check_sum (ospfh))
2305 {
2306 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2307 zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s",
2308 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2309 return 0;
2310 }
2311 return 1;
2312 case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */
2313 if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi)))
2314 {
2315 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2316 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple",
2317 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2318 return 0;
2319 }
2320 if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2321 {
2322 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2323 zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi));
2324 return 0;
2325 }
2326 if (! ospf_check_sum (ospfh))
2327 {
2328 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2329 zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s",
2330 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2331 return 0;
2332 }
2333 return 1;
2334 case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */
2335 if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi)))
2336 {
2337 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2338 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2339 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2340 return 0;
2341 }
2342 if (ospfh->checksum)
2343 {
2344 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2345 zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi));
2346 return 0;
2347 }
2348 /* only MD5 crypto method can pass ospf_packet_examin() */
2349 if
2350 (
2351 NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) ||
2352 ospfh->u.crypt.key_id != ck->key_id ||
2353 /* Condition above uses the last key ID on the list, which is
2354 different from what ospf_crypt_key_lookup() does. A bug? */
2355 ! ospf_check_md5_digest (oi, ospfh)
2356 )
2357 {
2358 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2359 zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi));
2360 return 0;
2361 }
2362 return 1;
2363 default:
2364 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2365 zlog_warn ("interface %s: invalid packet auth-type (%02x)",
2366 IF_NAME (oi), pkt_auth_type);
2367 return 0;
2368 }
paul718e3742002-12-13 20:15:29 +00002369}
2370
paul4dadc292005-05-06 21:37:42 +00002371static int
paul718e3742002-12-13 20:15:29 +00002372ospf_check_sum (struct ospf_header *ospfh)
2373{
2374 u_int32_t ret;
2375 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002376
2377 /* clear auth_data for checksum. */
2378 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2379
2380 /* keep checksum and clear. */
2381 sum = ospfh->checksum;
2382 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2383
2384 /* calculate checksum. */
2385 ret = in_cksum (ospfh, ntohs (ospfh->length));
2386
2387 if (ret != sum)
2388 {
2389 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2390 ret, sum);
2391 return 0;
2392 }
2393
2394 return 1;
2395}
2396
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002397/* Verify, that given link/TOS records are properly sized/aligned and match
2398 Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2399static unsigned
2400ospf_router_lsa_links_examin
2401(
2402 struct router_lsa_link * link,
2403 u_int16_t linkbytes,
2404 const u_int16_t num_links
2405)
2406{
2407 unsigned counted_links = 0, thislinklen;
2408
2409 while (linkbytes)
2410 {
2411 thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
2412 if (thislinklen > linkbytes)
2413 {
2414 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2415 zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
2416 return MSG_NG;
2417 }
2418 link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
2419 linkbytes -= thislinklen;
2420 counted_links++;
2421 }
2422 if (counted_links != num_links)
2423 {
2424 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2425 zlog_debug ("%s: %u link blocks declared, %u present",
2426 __func__, num_links, counted_links);
2427 return MSG_NG;
2428 }
2429 return MSG_OK;
2430}
2431
2432/* Verify, that the given LSA is properly sized/aligned (including type-specific
2433 minimum length constraint). */
2434static unsigned
2435ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
2436{
2437 unsigned ret;
2438 struct router_lsa * rlsa;
2439 if
2440 (
2441 lsah->type < OSPF_MAX_LSA &&
2442 ospf_lsa_minlen[lsah->type] &&
2443 lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
2444 )
2445 {
2446 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2447 zlog_debug ("%s: undersized (%u B) %s",
2448 __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
2449 return MSG_NG;
2450 }
2451 switch (lsah->type)
2452 {
2453 case OSPF_ROUTER_LSA:
2454 /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
2455 if (headeronly)
2456 {
2457 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2458 break;
2459 }
2460 rlsa = (struct router_lsa *) lsah;
2461 ret = ospf_router_lsa_links_examin
2462 (
2463 (struct router_lsa_link *) rlsa->link,
2464 lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
2465 ntohs (rlsa->links) /* 16 bits */
2466 );
2467 break;
2468 case OSPF_AS_EXTERNAL_LSA:
2469 /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
2470 case OSPF_AS_NSSA_LSA:
2471 /* RFC3101 C, idem */
2472 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
2473 break;
2474 /* Following LSA types are considered OK length-wise as soon as their minimum
2475 * length constraint is met and length of the whole LSA is a multiple of 4
2476 * (basic LSA header size is already a multiple of 4). */
2477 case OSPF_NETWORK_LSA:
2478 /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2479 case OSPF_SUMMARY_LSA:
2480 case OSPF_ASBR_SUMMARY_LSA:
2481 /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
2482#ifdef HAVE_OPAQUE_LSA
2483 case OSPF_OPAQUE_LINK_LSA:
2484 case OSPF_OPAQUE_AREA_LSA:
2485 case OSPF_OPAQUE_AS_LSA:
2486 /* RFC5250 A.2, "some number of octets (of application-specific
2487 * data) padded to 32-bit alignment." This is considered equivalent
2488 * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
2489 * file for the detailed analysis of this passage. */
2490#endif
2491 ret = lsalen % 4 ? MSG_NG : MSG_OK;
2492 break;
2493 default:
2494 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2495 zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
2496 return MSG_NG;
2497 }
2498 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2499 zlog_debug ("%s: alignment error in %s",
2500 __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
2501 return ret;
2502}
2503
2504/* Verify if the provided input buffer is a valid sequence of LSAs. This
2505 includes verification of LSA blocks length/alignment and dispatching
2506 of deeper-level checks. */
2507static unsigned
2508ospf_lsaseq_examin
2509(
2510 struct lsa_header *lsah, /* start of buffered data */
2511 size_t length,
2512 const u_char headeronly,
2513 /* When declared_num_lsas is not 0, compare it to the real number of LSAs
2514 and treat the difference as an error. */
2515 const u_int32_t declared_num_lsas
2516)
2517{
2518 u_int32_t counted_lsas = 0;
2519
2520 while (length)
2521 {
2522 u_int16_t lsalen;
2523 if (length < OSPF_LSA_HEADER_SIZE)
2524 {
2525 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2526 zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
2527 __func__, length, counted_lsas);
2528 return MSG_NG;
2529 }
2530 /* save on ntohs() calls here and in the LSA validator */
2531 lsalen = ntohs (lsah->length);
2532 if (lsalen < OSPF_LSA_HEADER_SIZE)
2533 {
2534 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2535 zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
2536 __func__, counted_lsas, lsalen);
2537 return MSG_NG;
2538 }
2539 if (headeronly)
2540 {
2541 /* less checks here and in ospf_lsa_examin() */
2542 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
2543 {
2544 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2545 zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
2546 return MSG_NG;
2547 }
2548 lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
2549 length -= OSPF_LSA_HEADER_SIZE;
2550 }
2551 else
2552 {
2553 /* make sure the input buffer is deep enough before further checks */
2554 if (lsalen > length)
2555 {
2556 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2557 zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2558 __func__, counted_lsas, lsalen, length);
2559 return MSG_NG;
2560 }
2561 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
2562 {
2563 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2564 zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
2565 return MSG_NG;
2566 }
2567 lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
2568 length -= lsalen;
2569 }
2570 counted_lsas++;
2571 }
2572
2573 if (declared_num_lsas && counted_lsas != declared_num_lsas)
2574 {
2575 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2576 zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
2577 __func__, declared_num_lsas, counted_lsas);
2578 return MSG_NG;
2579 }
2580 return MSG_OK;
2581}
2582
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002583/* Verify a complete OSPF packet for proper sizing/alignment. */
2584static unsigned
2585ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2586{
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002587 u_int16_t bytesdeclared, bytesauth;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002588 unsigned ret;
2589 struct ospf_ls_update * lsupd;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002590
2591 /* Length, 1st approximation. */
2592 if (bytesonwire < OSPF_HEADER_SIZE)
2593 {
2594 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2595 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2596 return MSG_NG;
2597 }
2598 /* Now it is safe to access header fields. Performing length check, allow
2599 * for possible extra bytes of crypto auth/padding, which are not counted
2600 * in the OSPF header "length" field. */
Denis Ovsienkoaee56742012-02-28 15:15:29 +04002601 if (oh->version != OSPF_VERSION)
2602 {
2603 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2604 zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
2605 return MSG_NG;
2606 }
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002607 bytesdeclared = ntohs (oh->length);
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002608 if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2609 bytesauth = 0;
2610 else
2611 {
2612 if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE)
2613 {
2614 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2615 zlog_debug ("%s: unsupported crypto auth length (%u B)",
2616 __func__, oh->u.crypt.auth_data_len);
2617 return MSG_NG;
2618 }
2619 bytesauth = OSPF_AUTH_MD5_SIZE;
2620 }
2621 if (bytesdeclared + bytesauth > bytesonwire)
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002622 {
2623 if (IS_DEBUG_OSPF_PACKET (0, RECV))
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002624 zlog_debug ("%s: packet length error (%u real, %u+%u declared)",
2625 __func__, bytesonwire, bytesdeclared, bytesauth);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002626 return MSG_NG;
2627 }
2628 /* Length, 2nd approximation. The type-specific constraint is checked
2629 against declared length, not amount of bytes on wire. */
2630 if
2631 (
2632 oh->type >= OSPF_MSG_HELLO &&
2633 oh->type <= OSPF_MSG_LS_ACK &&
2634 bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2635 )
2636 {
2637 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2638 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2639 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2640 return MSG_NG;
2641 }
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002642 switch (oh->type)
2643 {
2644 case OSPF_MSG_HELLO:
2645 /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
2646 by N>=0 router-IDs. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002647 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002648 break;
2649 case OSPF_MSG_DB_DESC:
2650 /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
2651 by N>=0 header-only LSAs. */
2652 ret = ospf_lsaseq_examin
2653 (
2654 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002655 bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002656 1, /* header-only LSAs */
2657 0
2658 );
2659 break;
2660 case OSPF_MSG_LS_REQ:
2661 /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002662 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002663 OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
2664 break;
2665 case OSPF_MSG_LS_UPD:
2666 /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
2667 by N>=0 full LSAs (with N declared beforehand). */
2668 lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
2669 ret = ospf_lsaseq_examin
2670 (
2671 (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002672 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002673 0, /* full LSAs */
2674 ntohl (lsupd->num_lsas) /* 32 bits */
2675 );
2676 break;
2677 case OSPF_MSG_LS_ACK:
2678 /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
2679 ret = ospf_lsaseq_examin
2680 (
2681 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002682 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002683 1, /* header-only LSAs */
2684 0
2685 );
2686 break;
2687 default:
2688 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2689 zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
2690 return MSG_NG;
2691 }
2692 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2693 zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
2694 return ret;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002695}
2696
paul718e3742002-12-13 20:15:29 +00002697/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002698static int
paul718e3742002-12-13 20:15:29 +00002699ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2700 struct ip *iph, struct ospf_header *ospfh)
2701{
paul718e3742002-12-13 20:15:29 +00002702 /* Check Area ID. */
2703 if (!ospf_check_area_id (oi, ospfh))
2704 {
2705 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2706 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2707 return -1;
2708 }
2709
2710 /* Check network mask, Silently discarded. */
2711 if (! ospf_check_network_mask (oi, iph->ip_src))
2712 {
2713 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2714 IF_NAME (oi), inet_ntoa (iph->ip_src));
2715 return -1;
2716 }
2717
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002718 /* Check authentication. The function handles logging actions, where required. */
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002719 if (! ospf_check_auth (oi, ospfh))
Denis Ovsienkobd5651f2012-02-26 17:59:43 +04002720 return -1;
paul718e3742002-12-13 20:15:29 +00002721
2722 return 0;
2723}
2724
2725/* Starting point of packet process function. */
2726int
2727ospf_read (struct thread *thread)
2728{
2729 int ret;
2730 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002731 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002732 struct ospf_interface *oi;
2733 struct ip *iph;
2734 struct ospf_header *ospfh;
2735 u_int16_t length;
2736 struct interface *ifp;
2737
2738 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002739 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002740
2741 /* prepare for next packet. */
2742 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002743
ajs5c333492005-02-23 15:43:01 +00002744 stream_reset(ospf->ibuf);
2745 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002746 return -1;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002747 /* This raw packet is known to be at least as big as its IP header. */
paul718e3742002-12-13 20:15:29 +00002748
ajs5c333492005-02-23 15:43:01 +00002749 /* Note that there should not be alignment problems with this assignment
2750 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002751 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002752 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002753
paulac191232004-10-22 12:05:17 +00002754 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002755 /* Handle cases where the platform does not support retrieving the ifindex,
2756 and also platforms (such as Solaris 8) that claim to support ifindex
2757 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002758 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002759
pauld3f0d622004-05-05 15:27:15 +00002760 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002761 return 0;
paul718e3742002-12-13 20:15:29 +00002762
2763 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002764 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002765 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002766
paul718e3742002-12-13 20:15:29 +00002767 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002768 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002769 {
pauld3241812003-09-29 12:42:39 +00002770 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2771 {
ajs2a42e282004-12-08 18:43:03 +00002772 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002773 inet_ntoa (iph->ip_src));
2774 }
paul718e3742002-12-13 20:15:29 +00002775 return 0;
2776 }
2777
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002778 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2779 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002780 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002781
paul718e3742002-12-13 20:15:29 +00002782 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002783 if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
2784 return -1;
2785 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002786
2787 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002788 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002789
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002790 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2791 after the passive/backbone/other checks below are passed. These checks
2792 in turn access the fields of unverified "ospfh" structure for their own
2793 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002794
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002795 /* If incoming interface is passive one, ignore it. */
2796 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2797 {
2798 char buf[3][INET_ADDRSTRLEN];
2799
2800 if (IS_DEBUG_OSPF_EVENT)
2801 zlog_debug ("ignoring packet from router %s sent to %s, "
2802 "received on a passive interface, %s",
2803 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2804 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2805 inet_ntop(AF_INET, &oi->address->u.prefix4,
2806 buf[2], sizeof(buf[2])));
2807
2808 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2809 {
2810 /* Try to fix multicast membership.
2811 * Some OS:es may have problems in this area,
2812 * make sure it is removed.
2813 */
2814 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2815 ospf_if_set_multicast(oi);
2816 }
2817 return 0;
2818 }
2819
2820
pauld3f0d622004-05-05 15:27:15 +00002821 /* if no local ospf_interface,
2822 * or header area is backbone but ospf_interface is not
2823 * check for VLINK interface
2824 */
2825 if ( (oi == NULL) ||
2826 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2827 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2828 )
2829 {
2830 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2831 {
Paul Jakma88871b12006-06-15 11:41:19 +00002832 if (IS_DEBUG_OSPF_EVENT)
2833 zlog_debug ("Packet from [%s] received on link %s"
2834 " but no ospf_interface",
2835 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002836 return 0;
2837 }
2838 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002839
pauld3f0d622004-05-05 15:27:15 +00002840 /* else it must be a local ospf interface, check it was received on
2841 * correct link
2842 */
2843 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002844 {
Paul Jakma11637432009-08-11 12:25:42 +01002845 if (IS_DEBUG_OSPF_EVENT)
2846 zlog_warn ("Packet from [%s] received on wrong link %s",
2847 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002848 return 0;
2849 }
ajs847947f2005-02-02 18:38:48 +00002850 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002851 {
ajsba6454e2005-02-08 15:37:30 +00002852 char buf[2][INET_ADDRSTRLEN];
2853 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002854 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002855 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2856 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2857 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002858 /* Fix multicast memberships? */
2859 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002860 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002861 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002862 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002863 if (oi->multicast_memberships)
2864 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002865 return 0;
2866 }
paul718e3742002-12-13 20:15:29 +00002867
2868 /*
2869 * If the received packet is destined for AllDRouters, the packet
2870 * should be accepted only if the received ospf interface state is
2871 * either DR or Backup -- endo.
2872 */
2873 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2874 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2875 {
ajsba6454e2005-02-08 15:37:30 +00002876 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002877 inet_ntoa (iph->ip_src), IF_NAME (oi),
2878 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002879 /* Try to fix multicast membership. */
2880 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2881 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002882 return 0;
2883 }
2884
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002885 /* Verify more OSPF header fields. */
2886 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2887 if (ret < 0)
2888 {
2889 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2890 zlog_debug ("ospf_read[%s]: Header check failed, "
2891 "dropping.",
2892 inet_ntoa (iph->ip_src));
2893 return ret;
2894 }
2895
paul718e3742002-12-13 20:15:29 +00002896 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002897 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2898 {
paul718e3742002-12-13 20:15:29 +00002899 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002900 {
ajs2a42e282004-12-08 18:43:03 +00002901 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002902 ospf_packet_dump (ibuf);
2903 }
paul718e3742002-12-13 20:15:29 +00002904
ajs2a42e282004-12-08 18:43:03 +00002905 zlog_debug ("%s received from [%s] via [%s]",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +04002906 LOOKUP (ospf_packet_type_str, ospfh->type),
paul1aa7b392003-04-08 08:51:58 +00002907 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002908 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2909 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002910
2911 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002912 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002913 }
paul718e3742002-12-13 20:15:29 +00002914
paul9985f832005-02-09 15:51:56 +00002915 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002916
2917 /* Adjust size to message length. */
2918 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2919
2920 /* Read rest of the packet and call each sort of packet routine. */
2921 switch (ospfh->type)
2922 {
2923 case OSPF_MSG_HELLO:
2924 ospf_hello (iph, ospfh, ibuf, oi, length);
2925 break;
2926 case OSPF_MSG_DB_DESC:
2927 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2928 break;
2929 case OSPF_MSG_LS_REQ:
2930 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2931 break;
2932 case OSPF_MSG_LS_UPD:
2933 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2934 break;
2935 case OSPF_MSG_LS_ACK:
2936 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2937 break;
2938 default:
2939 zlog (NULL, LOG_WARNING,
2940 "interface %s: OSPF packet header type %d is illegal",
2941 IF_NAME (oi), ospfh->type);
2942 break;
2943 }
2944
paul718e3742002-12-13 20:15:29 +00002945 return 0;
2946}
2947
2948/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002949static void
paul718e3742002-12-13 20:15:29 +00002950ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2951{
2952 struct ospf_header *ospfh;
2953
2954 ospfh = (struct ospf_header *) STREAM_DATA (s);
2955
2956 ospfh->version = (u_char) OSPF_VERSION;
2957 ospfh->type = (u_char) type;
2958
paul68980082003-03-25 05:07:42 +00002959 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002960
2961 ospfh->checksum = 0;
2962 ospfh->area_id = oi->area->area_id;
2963 ospfh->auth_type = htons (ospf_auth_type (oi));
2964
2965 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2966
paul9985f832005-02-09 15:51:56 +00002967 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002968}
2969
2970/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002971static int
paul718e3742002-12-13 20:15:29 +00002972ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2973{
2974 struct crypt_key *ck;
2975
2976 switch (ospf_auth_type (oi))
2977 {
2978 case OSPF_AUTH_NULL:
2979 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2980 break;
2981 case OSPF_AUTH_SIMPLE:
2982 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2983 OSPF_AUTH_SIMPLE_SIZE);
2984 break;
2985 case OSPF_AUTH_CRYPTOGRAPHIC:
2986 /* If key is not set, then set 0. */
2987 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2988 {
2989 ospfh->u.crypt.zero = 0;
2990 ospfh->u.crypt.key_id = 0;
2991 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2992 }
2993 else
2994 {
paul1eb8ef22005-04-07 07:30:20 +00002995 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002996 ospfh->u.crypt.zero = 0;
2997 ospfh->u.crypt.key_id = ck->key_id;
2998 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2999 }
3000 /* note: the seq is done in ospf_make_md5_digest() */
3001 break;
3002 default:
3003 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
3004 break;
3005 }
3006
3007 return 0;
3008}
3009
3010/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00003011static void
paul718e3742002-12-13 20:15:29 +00003012ospf_fill_header (struct ospf_interface *oi,
3013 struct stream *s, u_int16_t length)
3014{
3015 struct ospf_header *ospfh;
3016
3017 ospfh = (struct ospf_header *) STREAM_DATA (s);
3018
3019 /* Fill length. */
3020 ospfh->length = htons (length);
3021
3022 /* Calculate checksum. */
3023 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
3024 ospfh->checksum = in_cksum (ospfh, length);
3025 else
3026 ospfh->checksum = 0;
3027
3028 /* Add Authentication Data. */
3029 ospf_make_auth (oi, ospfh);
3030}
3031
paul4dadc292005-05-06 21:37:42 +00003032static int
paul718e3742002-12-13 20:15:29 +00003033ospf_make_hello (struct ospf_interface *oi, struct stream *s)
3034{
3035 struct ospf_neighbor *nbr;
3036 struct route_node *rn;
3037 u_int16_t length = OSPF_HELLO_MIN_SIZE;
3038 struct in_addr mask;
3039 unsigned long p;
3040 int flag = 0;
3041
3042 /* Set netmask of interface. */
3043 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
3044 oi->type != OSPF_IFTYPE_VIRTUALLINK)
3045 masklen2ip (oi->address->prefixlen, &mask);
3046 else
3047 memset ((char *) &mask, 0, sizeof (struct in_addr));
3048 stream_put_ipv4 (s, mask.s_addr);
3049
3050 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00003051 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
3052 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
3053 else
3054 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00003055
3056 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003057 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00003058 OPTIONS(oi), IF_NAME (oi));
3059
3060 /* Set Options. */
3061 stream_putc (s, OPTIONS (oi));
3062
3063 /* Set Router Priority. */
3064 stream_putc (s, PRIORITY (oi));
3065
3066 /* Set Router Dead Interval. */
3067 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
3068
3069 /* Set Designated Router. */
3070 stream_put_ipv4 (s, DR (oi).s_addr);
3071
paul9985f832005-02-09 15:51:56 +00003072 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003073
3074 /* Set Backup Designated Router. */
3075 stream_put_ipv4 (s, BDR (oi).s_addr);
3076
3077 /* Add neighbor seen. */
3078 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00003079 if ((nbr = rn->info))
3080 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
3081 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
3082 if (nbr->state != NSM_Down) /* This is myself for DR election. */
3083 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003084 {
3085 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00003086 if (nbr->d_router.s_addr != 0
3087 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
3088 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
3089 flag = 1;
paul718e3742002-12-13 20:15:29 +00003090
3091 stream_put_ipv4 (s, nbr->router_id.s_addr);
3092 length += 4;
3093 }
3094
3095 /* Let neighbor generate BackupSeen. */
3096 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00003097 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00003098
3099 return length;
3100}
3101
paul4dadc292005-05-06 21:37:42 +00003102static int
paul718e3742002-12-13 20:15:29 +00003103ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
3104 struct stream *s)
3105{
3106 struct ospf_lsa *lsa;
3107 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
3108 u_char options;
3109 unsigned long pp;
3110 int i;
3111 struct ospf_lsdb *lsdb;
3112
3113 /* Set Interface MTU. */
3114 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3115 stream_putw (s, 0);
3116 else
3117 stream_putw (s, oi->ifp->mtu);
3118
3119 /* Set Options. */
3120 options = OPTIONS (oi);
3121#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003122 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00003123 {
3124 if (IS_SET_DD_I (nbr->dd_flags)
3125 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
3126 /*
3127 * Set O-bit in the outgoing DD packet for capablity negotiation,
3128 * if one of following case is applicable.
3129 *
3130 * 1) WaitTimer expiration event triggered the neighbor state to
3131 * change to Exstart, but no (valid) DD packet has received
3132 * from the neighbor yet.
3133 *
3134 * 2) At least one DD packet with O-bit on has received from the
3135 * neighbor.
3136 */
3137 SET_FLAG (options, OSPF_OPTION_O);
3138 }
3139#endif /* HAVE_OPAQUE_LSA */
3140 stream_putc (s, options);
3141
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003142 /* DD flags */
paul9985f832005-02-09 15:51:56 +00003143 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003144 stream_putc (s, nbr->dd_flags);
3145
3146 /* Set DD Sequence Number. */
3147 stream_putl (s, nbr->dd_seqnum);
3148
Paul Jakmab5aeb442006-08-30 18:47:37 +00003149 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00003150 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00003151 goto empty;
paul718e3742002-12-13 20:15:29 +00003152
3153 /* Describe LSA Header from Database Summary List. */
3154 lsdb = &nbr->db_sum;
3155
3156 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3157 {
3158 struct route_table *table = lsdb->type[i].db;
3159 struct route_node *rn;
3160
3161 for (rn = route_top (table); rn; rn = route_next (rn))
3162 if ((lsa = rn->info) != NULL)
3163 {
3164#ifdef HAVE_OPAQUE_LSA
3165 if (IS_OPAQUE_LSA (lsa->data->type)
3166 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
3167 {
3168 /* Suppress advertising opaque-informations. */
3169 /* Remove LSA from DB summary list. */
3170 ospf_lsdb_delete (lsdb, lsa);
3171 continue;
3172 }
3173#endif /* HAVE_OPAQUE_LSA */
3174
3175 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
3176 {
3177 struct lsa_header *lsah;
3178 u_int16_t ls_age;
3179
3180 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003181 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003182 break;
3183
3184 /* Keep pointer to LS age. */
3185 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00003186 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003187
3188 /* Proceed stream pointer. */
3189 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3190 length += OSPF_LSA_HEADER_SIZE;
3191
3192 /* Set LS age. */
3193 ls_age = LS_AGE (lsa);
3194 lsah->ls_age = htons (ls_age);
3195
3196 }
3197
3198 /* Remove LSA from DB summary list. */
3199 ospf_lsdb_delete (lsdb, lsa);
3200 }
3201 }
3202
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003203 /* Update 'More' bit */
3204 if (ospf_db_summary_isempty (nbr))
3205 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00003206empty:
3207 if (nbr->state >= NSM_Exchange)
3208 {
3209 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
3210 /* Rewrite DD flags */
3211 stream_putc_at (s, pp, nbr->dd_flags);
3212 }
3213 else
3214 {
3215 assert (IS_SET_DD_M(nbr->dd_flags));
3216 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003217 }
paul718e3742002-12-13 20:15:29 +00003218 return length;
3219}
3220
paul4dadc292005-05-06 21:37:42 +00003221static int
paul718e3742002-12-13 20:15:29 +00003222ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
3223 unsigned long delta, struct ospf_neighbor *nbr,
3224 struct ospf_lsa *lsa)
3225{
3226 struct ospf_interface *oi;
3227
3228 oi = nbr->oi;
3229
3230 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003231 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00003232 return 0;
3233
3234 stream_putl (s, lsa->data->type);
3235 stream_put_ipv4 (s, lsa->data->id.s_addr);
3236 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
3237
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003238 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00003239 nbr->ls_req_last = ospf_lsa_lock (lsa);
3240
3241 *length += 12;
3242 return 1;
3243}
3244
paul4dadc292005-05-06 21:37:42 +00003245static int
paul718e3742002-12-13 20:15:29 +00003246ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
3247{
3248 struct ospf_lsa *lsa;
3249 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003250 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00003251 struct route_table *table;
3252 struct route_node *rn;
3253 int i;
3254 struct ospf_lsdb *lsdb;
3255
3256 lsdb = &nbr->ls_req;
3257
3258 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3259 {
3260 table = lsdb->type[i].db;
3261 for (rn = route_top (table); rn; rn = route_next (rn))
3262 if ((lsa = (rn->info)) != NULL)
3263 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
3264 {
3265 route_unlock_node (rn);
3266 break;
3267 }
3268 }
3269 return length;
3270}
3271
paul4dadc292005-05-06 21:37:42 +00003272static int
paul718e3742002-12-13 20:15:29 +00003273ls_age_increment (struct ospf_lsa *lsa, int delay)
3274{
3275 int age;
3276
3277 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
3278
3279 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3280}
3281
paul4dadc292005-05-06 21:37:42 +00003282static int
hasso52dc7ee2004-09-23 19:18:23 +00003283ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003284{
3285 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00003286 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003287 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00003288 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00003289 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003290 unsigned long pp;
3291 int count = 0;
3292
3293 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003294 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00003295
paul9985f832005-02-09 15:51:56 +00003296 pp = stream_get_endp (s);
3297 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003298 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00003299
gdt86f1fd92005-01-10 14:20:43 +00003300 /* Calculate amount of packet usable for data. */
3301 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3302
paul718e3742002-12-13 20:15:29 +00003303 while ((node = listhead (update)) != NULL)
3304 {
3305 struct lsa_header *lsah;
3306 u_int16_t ls_age;
3307
3308 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003309 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00003310
paul1eb8ef22005-04-07 07:30:20 +00003311 lsa = listgetdata (node);
3312
paul718e3742002-12-13 20:15:29 +00003313 assert (lsa->data);
3314
paul68b73392004-09-12 14:21:37 +00003315 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00003316 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00003317 break;
3318
paul718e3742002-12-13 20:15:29 +00003319 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00003320 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003321
3322 /* Put LSA to Link State Request. */
3323 stream_put (s, lsa->data, ntohs (lsa->data->length));
3324
3325 /* Set LS age. */
3326 /* each hop must increment an lsa_age by transmit_delay
3327 of OSPF interface */
3328 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3329 lsah->ls_age = htons (ls_age);
3330
3331 length += ntohs (lsa->data->length);
3332 count++;
3333
3334 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003335 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003336 }
3337
3338 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003339 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003340
3341 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003342 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003343 return length;
3344}
3345
paul4dadc292005-05-06 21:37:42 +00003346static int
hasso52dc7ee2004-09-23 19:18:23 +00003347ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003348{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003349 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003350 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003351 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003352 struct ospf_lsa *lsa;
3353
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003354 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003355 {
paul718e3742002-12-13 20:15:29 +00003356 assert (lsa);
3357
gdt86f1fd92005-01-10 14:20:43 +00003358 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003359 break;
3360
3361 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3362 length += OSPF_LSA_HEADER_SIZE;
3363
paul718e3742002-12-13 20:15:29 +00003364 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003365 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003366 }
3367
paul718e3742002-12-13 20:15:29 +00003368 return length;
3369}
3370
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003371static void
3372ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003373{
3374 struct ospf_packet *op;
3375 u_int16_t length = OSPF_HEADER_SIZE;
3376
3377 op = ospf_packet_new (oi->ifp->mtu);
3378
3379 /* Prepare OSPF common header. */
3380 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3381
3382 /* Prepare OSPF Hello body. */
3383 length += ospf_make_hello (oi, op->s);
3384
3385 /* Fill OSPF header. */
3386 ospf_fill_header (oi, op->s, length);
3387
3388 /* Set packet length. */
3389 op->length = length;
3390
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003391 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003392
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003393 /* Add packet to the top of the interface output queue, so that they
3394 * can't get delayed by things like long queues of LS Update packets
3395 */
3396 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003397
3398 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003399 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003400}
3401
paul4dadc292005-05-06 21:37:42 +00003402static void
paul718e3742002-12-13 20:15:29 +00003403ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3404{
3405 struct ospf_interface *oi;
3406
3407 oi = nbr_nbma->oi;
3408 assert(oi);
3409
3410 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003411 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003412 return;
3413
3414 if (oi->type != OSPF_IFTYPE_NBMA)
3415 return;
3416
3417 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3418 return;
3419
3420 if (PRIORITY(oi) == 0)
3421 return;
3422
3423 if (nbr_nbma->priority == 0
3424 && oi->state != ISM_DR && oi->state != ISM_Backup)
3425 return;
3426
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003427 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003428}
3429
3430int
3431ospf_poll_timer (struct thread *thread)
3432{
3433 struct ospf_nbr_nbma *nbr_nbma;
3434
3435 nbr_nbma = THREAD_ARG (thread);
3436 nbr_nbma->t_poll = NULL;
3437
3438 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003439 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003440 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3441
3442 ospf_poll_send (nbr_nbma);
3443
3444 if (nbr_nbma->v_poll > 0)
3445 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3446 nbr_nbma->v_poll);
3447
3448 return 0;
3449}
3450
3451
3452int
3453ospf_hello_reply_timer (struct thread *thread)
3454{
3455 struct ospf_neighbor *nbr;
3456
3457 nbr = THREAD_ARG (thread);
3458 nbr->t_hello_reply = NULL;
3459
3460 assert (nbr->oi);
3461
3462 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003463 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003464 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3465
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003466 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003467
3468 return 0;
3469}
3470
3471/* Send OSPF Hello. */
3472void
3473ospf_hello_send (struct ospf_interface *oi)
3474{
paul718e3742002-12-13 20:15:29 +00003475 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003476 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003477 return;
3478
paul718e3742002-12-13 20:15:29 +00003479 if (oi->type == OSPF_IFTYPE_NBMA)
3480 {
3481 struct ospf_neighbor *nbr;
3482 struct route_node *rn;
3483
3484 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3485 if ((nbr = rn->info))
3486 if (nbr != oi->nbr_self)
3487 if (nbr->state != NSM_Down)
3488 {
3489 /* RFC 2328 Section 9.5.1
3490 If the router is not eligible to become Designated Router,
3491 it must periodically send Hello Packets to both the
3492 Designated Router and the Backup Designated Router (if they
3493 exist). */
3494 if (PRIORITY(oi) == 0 &&
3495 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3496 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3497 continue;
3498
3499 /* If the router is eligible to become Designated Router, it
3500 must periodically send Hello Packets to all neighbors that
3501 are also eligible. In addition, if the router is itself the
3502 Designated Router or Backup Designated Router, it must also
3503 send periodic Hello Packets to all other neighbors. */
3504
3505 if (nbr->priority == 0 && oi->state == ISM_DROther)
3506 continue;
3507 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003508 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003509 }
paul718e3742002-12-13 20:15:29 +00003510 }
3511 else
3512 {
3513 /* Decide destination address. */
3514 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003515 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3516 else
3517 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003518 }
3519}
3520
3521/* Send OSPF Database Description. */
3522void
3523ospf_db_desc_send (struct ospf_neighbor *nbr)
3524{
3525 struct ospf_interface *oi;
3526 struct ospf_packet *op;
3527 u_int16_t length = OSPF_HEADER_SIZE;
3528
3529 oi = nbr->oi;
3530 op = ospf_packet_new (oi->ifp->mtu);
3531
3532 /* Prepare OSPF common header. */
3533 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3534
3535 /* Prepare OSPF Database Description body. */
3536 length += ospf_make_db_desc (oi, nbr, op->s);
3537
3538 /* Fill OSPF header. */
3539 ospf_fill_header (oi, op->s, length);
3540
3541 /* Set packet length. */
3542 op->length = length;
3543
3544 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003545 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3546 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3547 else
3548 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003549
3550 /* Add packet to the interface output queue. */
3551 ospf_packet_add (oi, op);
3552
3553 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003554 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003555
3556 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3557 if (nbr->last_send)
3558 ospf_packet_free (nbr->last_send);
3559 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003560 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003561}
3562
3563/* Re-send Database Description. */
3564void
3565ospf_db_desc_resend (struct ospf_neighbor *nbr)
3566{
3567 struct ospf_interface *oi;
3568
3569 oi = nbr->oi;
3570
3571 /* Add packet to the interface output queue. */
3572 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3573
3574 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003575 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003576}
3577
3578/* Send Link State Request. */
3579void
3580ospf_ls_req_send (struct ospf_neighbor *nbr)
3581{
3582 struct ospf_interface *oi;
3583 struct ospf_packet *op;
3584 u_int16_t length = OSPF_HEADER_SIZE;
3585
3586 oi = nbr->oi;
3587 op = ospf_packet_new (oi->ifp->mtu);
3588
3589 /* Prepare OSPF common header. */
3590 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3591
3592 /* Prepare OSPF Link State Request body. */
3593 length += ospf_make_ls_req (nbr, op->s);
3594 if (length == OSPF_HEADER_SIZE)
3595 {
3596 ospf_packet_free (op);
3597 return;
3598 }
3599
3600 /* Fill OSPF header. */
3601 ospf_fill_header (oi, op->s, length);
3602
3603 /* Set packet length. */
3604 op->length = length;
3605
3606 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003607 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3608 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3609 else
3610 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003611
3612 /* Add packet to the interface output queue. */
3613 ospf_packet_add (oi, op);
3614
3615 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003616 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003617
3618 /* Add Link State Request Retransmission Timer. */
3619 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3620}
3621
3622/* Send Link State Update with an LSA. */
3623void
3624ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3625 int flag)
3626{
hasso52dc7ee2004-09-23 19:18:23 +00003627 struct list *update;
paul718e3742002-12-13 20:15:29 +00003628
3629 update = list_new ();
3630
3631 listnode_add (update, lsa);
3632 ospf_ls_upd_send (nbr, update, flag);
3633
3634 list_delete (update);
3635}
3636
paul68b73392004-09-12 14:21:37 +00003637/* Determine size for packet. Must be at least big enough to accomodate next
3638 * LSA on list, which may be bigger than MTU size.
3639 *
3640 * Return pointer to new ospf_packet
3641 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3642 * on packet sizes (in which case offending LSA is deleted from update list)
3643 */
3644static struct ospf_packet *
3645ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3646{
3647 struct ospf_lsa *lsa;
3648 struct listnode *ln;
3649 size_t size;
3650 static char warned = 0;
3651
paul1eb8ef22005-04-07 07:30:20 +00003652 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003653 assert (lsa->data);
3654
3655 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3656 > ospf_packet_max (oi))
3657 {
3658 if (!warned)
3659 {
3660 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3661 "will need to fragment. Not optimal. Try divide up"
3662 " your network with areas. Use 'debug ospf packet send'"
3663 " to see details, or look at 'show ip ospf database ..'");
3664 warned = 1;
3665 }
3666
3667 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003668 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003669 " %d bytes originated by %s, will be fragmented!",
3670 inet_ntoa (lsa->data->id),
3671 ntohs (lsa->data->length),
3672 inet_ntoa (lsa->data->adv_router));
3673
3674 /*
3675 * Allocate just enough to fit this LSA only, to avoid including other
3676 * LSAs in fragmented LSA Updates.
3677 */
3678 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3679 + OSPF_LS_UPD_MIN_SIZE;
3680 }
3681 else
3682 size = oi->ifp->mtu;
3683
3684 if (size > OSPF_MAX_PACKET_SIZE)
3685 {
3686 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003687 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003688 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003689 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003690 (long int) size);
paul68b73392004-09-12 14:21:37 +00003691 list_delete_node (update, ln);
3692 return NULL;
3693 }
3694
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003695 /* IP header is built up separately by ospf_write(). This means, that we must
3696 * reduce the "affordable" size just calculated by length of an IP header.
3697 * This makes sure, that even if we manage to fill the payload with LSA data
3698 * completely, the final packet (our data plus IP header) still fits into
3699 * outgoing interface MTU. This correction isn't really meaningful for an
3700 * oversized LSA, but for consistency the correction is done for both cases.
3701 *
3702 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3703 */
3704 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003705}
3706
paul718e3742002-12-13 20:15:29 +00003707static void
hasso52dc7ee2004-09-23 19:18:23 +00003708ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003709 struct in_addr addr)
3710{
3711 struct ospf_packet *op;
3712 u_int16_t length = OSPF_HEADER_SIZE;
3713
3714 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003715 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003716
3717 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003718
3719 /* Prepare OSPF common header. */
3720 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3721
paul59ea14c2004-07-14 20:50:36 +00003722 /* Prepare OSPF Link State Update body.
3723 * Includes Type-7 translation.
3724 */
paul718e3742002-12-13 20:15:29 +00003725 length += ospf_make_ls_upd (oi, update, op->s);
3726
3727 /* Fill OSPF header. */
3728 ospf_fill_header (oi, op->s, length);
3729
3730 /* Set packet length. */
3731 op->length = length;
3732
3733 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003734 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3735 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3736 else
3737 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003738
3739 /* Add packet to the interface output queue. */
3740 ospf_packet_add (oi, op);
3741
3742 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003743 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003744}
3745
3746static int
3747ospf_ls_upd_send_queue_event (struct thread *thread)
3748{
3749 struct ospf_interface *oi = THREAD_ARG(thread);
3750 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003751 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003752 struct list *update;
paul68b73392004-09-12 14:21:37 +00003753 char again = 0;
paul718e3742002-12-13 20:15:29 +00003754
3755 oi->t_ls_upd_event = NULL;
3756
3757 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003758 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003759
paul736d3442003-07-24 23:22:57 +00003760 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003761 {
paul736d3442003-07-24 23:22:57 +00003762 rnext = route_next (rn);
3763
paul718e3742002-12-13 20:15:29 +00003764 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003765 continue;
paul68b73392004-09-12 14:21:37 +00003766
3767 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003768
paul48fe13b2004-07-27 17:40:44 +00003769 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003770
paul68b73392004-09-12 14:21:37 +00003771 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003772 if (listcount(update) == 0)
3773 {
3774 list_delete (rn->info);
3775 rn->info = NULL;
3776 route_unlock_node (rn);
3777 }
3778 else
paul68b73392004-09-12 14:21:37 +00003779 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003780 }
3781
3782 if (again != 0)
3783 {
3784 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003785 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003786 " %d nodes to try again, raising new event", again);
3787 oi->t_ls_upd_event =
3788 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003789 }
3790
3791 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003792 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003793
paul718e3742002-12-13 20:15:29 +00003794 return 0;
3795}
3796
3797void
hasso52dc7ee2004-09-23 19:18:23 +00003798ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003799{
3800 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003801 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003802 struct prefix_ipv4 p;
3803 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003804 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003805
3806 oi = nbr->oi;
3807
3808 p.family = AF_INET;
3809 p.prefixlen = IPV4_MAX_BITLEN;
3810
3811 /* Decide destination address. */
3812 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3813 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003814 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3815 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003816 else if (flag == OSPF_SEND_PACKET_DIRECT)
3817 p.prefix = nbr->address.u.prefix4;
3818 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3819 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003820 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3821 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003822 else
3823 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3824
3825 if (oi->type == OSPF_IFTYPE_NBMA)
3826 {
3827 if (flag == OSPF_SEND_PACKET_INDIRECT)
3828 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3829 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3830 zlog_warn ("* LS-Update is sent to myself.");
3831 }
3832
3833 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3834
3835 if (rn->info == NULL)
3836 rn->info = list_new ();
3837
paul1eb8ef22005-04-07 07:30:20 +00003838 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003839 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003840
3841 if (oi->t_ls_upd_event == NULL)
3842 oi->t_ls_upd_event =
3843 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3844}
3845
3846static void
hasso52dc7ee2004-09-23 19:18:23 +00003847ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3848 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003849{
3850 struct ospf_packet *op;
3851 u_int16_t length = OSPF_HEADER_SIZE;
3852
3853 op = ospf_packet_new (oi->ifp->mtu);
3854
3855 /* Prepare OSPF common header. */
3856 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3857
3858 /* Prepare OSPF Link State Acknowledgment body. */
3859 length += ospf_make_ls_ack (oi, ack, op->s);
3860
3861 /* Fill OSPF header. */
3862 ospf_fill_header (oi, op->s, length);
3863
3864 /* Set packet length. */
3865 op->length = length;
3866
3867 /* Set destination IP address. */
3868 op->dst = dst;
3869
3870 /* Add packet to the interface output queue. */
3871 ospf_packet_add (oi, op);
3872
3873 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003874 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003875}
3876
3877static int
3878ospf_ls_ack_send_event (struct thread *thread)
3879{
3880 struct ospf_interface *oi = THREAD_ARG (thread);
3881
3882 oi->t_ls_ack_direct = NULL;
3883
3884 while (listcount (oi->ls_ack_direct.ls_ack))
3885 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3886 oi->ls_ack_direct.dst);
3887
3888 return 0;
3889}
3890
3891void
3892ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3893{
3894 struct ospf_interface *oi = nbr->oi;
3895
3896 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3897 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3898
3899 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3900
3901 if (oi->t_ls_ack_direct == NULL)
3902 oi->t_ls_ack_direct =
3903 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3904}
3905
3906/* Send Link State Acknowledgment delayed. */
3907void
3908ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3909{
3910 struct in_addr dst;
3911
3912 /* Decide destination address. */
3913 /* RFC2328 Section 13.5 On non-broadcast
3914 networks, delayed Link State Acknowledgment packets must be
3915 unicast separately over each adjacency (i.e., neighbor whose
3916 state is >= Exchange). */
3917 if (oi->type == OSPF_IFTYPE_NBMA)
3918 {
3919 struct ospf_neighbor *nbr;
3920 struct route_node *rn;
3921
3922 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3923 if ((nbr = rn->info) != NULL)
3924 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3925 while (listcount (oi->ls_ack))
3926 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3927 return;
3928 }
3929 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3930 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3931 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3932 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3933 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3934 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003935 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3936 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003937 else
3938 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3939
3940 while (listcount (oi->ls_ack))
3941 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3942}