blob: 3d827296f77bb92d013afaf425adf59e3ba351fd [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
paul718e3742002-12-13 20:15:29 +000094/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000095static int
paul718e3742002-12-13 20:15:29 +000096ospf_auth_type (struct ospf_interface *oi)
97{
98 int auth_type;
99
100 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
101 auth_type = oi->area->auth_type;
102 else
103 auth_type = OSPF_IF_PARAM (oi, auth_type);
104
105 /* Handle case where MD5 key list is not configured aka Cisco */
106 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
107 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
108 return OSPF_AUTH_NULL;
109
110 return auth_type;
111
112}
113
paul718e3742002-12-13 20:15:29 +0000114struct ospf_packet *
115ospf_packet_new (size_t size)
116{
117 struct ospf_packet *new;
118
119 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
120 new->s = stream_new (size);
121
122 return new;
123}
124
125void
126ospf_packet_free (struct ospf_packet *op)
127{
128 if (op->s)
129 stream_free (op->s);
130
131 XFREE (MTYPE_OSPF_PACKET, op);
132
133 op = NULL;
134}
135
136struct ospf_fifo *
137ospf_fifo_new ()
138{
139 struct ospf_fifo *new;
140
141 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
142 return new;
143}
144
145/* Add new packet to fifo. */
146void
147ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
148{
149 if (fifo->tail)
150 fifo->tail->next = op;
151 else
152 fifo->head = op;
153
154 fifo->tail = op;
155
156 fifo->count++;
157}
158
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000159/* Add new packet to head of fifo. */
160static void
161ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
162{
163 op->next = fifo->head;
164
165 if (fifo->tail == NULL)
166 fifo->tail = op;
167
168 fifo->head = op;
169
170 fifo->count++;
171}
172
paul718e3742002-12-13 20:15:29 +0000173/* Delete first packet from fifo. */
174struct ospf_packet *
175ospf_fifo_pop (struct ospf_fifo *fifo)
176{
177 struct ospf_packet *op;
178
179 op = fifo->head;
180
181 if (op)
182 {
183 fifo->head = op->next;
184
185 if (fifo->head == NULL)
186 fifo->tail = NULL;
187
188 fifo->count--;
189 }
190
191 return op;
192}
193
194/* Return first fifo entry. */
195struct ospf_packet *
196ospf_fifo_head (struct ospf_fifo *fifo)
197{
198 return fifo->head;
199}
200
201/* Flush ospf packet fifo. */
202void
203ospf_fifo_flush (struct ospf_fifo *fifo)
204{
205 struct ospf_packet *op;
206 struct ospf_packet *next;
207
208 for (op = fifo->head; op; op = next)
209 {
210 next = op->next;
211 ospf_packet_free (op);
212 }
213 fifo->head = fifo->tail = NULL;
214 fifo->count = 0;
215}
216
217/* Free ospf packet fifo. */
218void
219ospf_fifo_free (struct ospf_fifo *fifo)
220{
221 ospf_fifo_flush (fifo);
222
223 XFREE (MTYPE_OSPF_FIFO, fifo);
224}
225
226void
227ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
228{
ajsc3eab872005-01-29 15:52:07 +0000229 if (!oi->obuf)
230 {
231 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
232 "destination %s) called with NULL obuf, ignoring "
233 "(please report this bug)!\n",
234 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400235 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
ajsc3eab872005-01-29 15:52:07 +0000236 inet_ntoa (op->dst));
237 return;
238 }
239
paul718e3742002-12-13 20:15:29 +0000240 /* Add packet to end of queue. */
241 ospf_fifo_push (oi->obuf, op);
242
243 /* Debug of packet fifo*/
244 /* ospf_fifo_debug (oi->obuf); */
245}
246
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000247static void
248ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
249{
250 if (!oi->obuf)
251 {
252 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
253 "destination %s) called with NULL obuf, ignoring "
254 "(please report this bug)!\n",
255 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko7e0e2cb2012-01-20 22:32:10 +0400256 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000257 inet_ntoa (op->dst));
258 return;
259 }
260
261 /* Add packet to head of queue. */
262 ospf_fifo_push_head (oi->obuf, op);
263
264 /* Debug of packet fifo*/
265 /* ospf_fifo_debug (oi->obuf); */
266}
267
paul718e3742002-12-13 20:15:29 +0000268void
269ospf_packet_delete (struct ospf_interface *oi)
270{
271 struct ospf_packet *op;
272
273 op = ospf_fifo_pop (oi->obuf);
274
275 if (op)
276 ospf_packet_free (op);
277}
278
paul718e3742002-12-13 20:15:29 +0000279struct ospf_packet *
280ospf_packet_dup (struct ospf_packet *op)
281{
282 struct ospf_packet *new;
283
paul37163d62003-02-03 18:40:56 +0000284 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000285 /* XXX size_t */
286 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
287 (u_long)STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000288
289 /* Reserve space for MD5 authentication that may be added later. */
290 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000291 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000292
293 new->dst = op->dst;
294 new->length = op->length;
295
296 return new;
297}
298
gdt86f1fd92005-01-10 14:20:43 +0000299/* XXX inline */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100300static unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000301ospf_packet_authspace (struct ospf_interface *oi)
302{
303 int auth = 0;
304
305 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
306 auth = OSPF_AUTH_MD5_SIZE;
307
308 return auth;
309}
310
paul4dadc292005-05-06 21:37:42 +0000311static unsigned int
paul718e3742002-12-13 20:15:29 +0000312ospf_packet_max (struct ospf_interface *oi)
313{
314 int max;
315
gdt86f1fd92005-01-10 14:20:43 +0000316 max = oi->ifp->mtu - ospf_packet_authspace(oi);
317
paul68b73392004-09-12 14:21:37 +0000318 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000319
320 return max;
321}
322
323
paul4dadc292005-05-06 21:37:42 +0000324static int
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400325ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +0000326{
vincentc1a03d42005-09-28 15:47:44 +0000327 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000328 unsigned char digest[OSPF_AUTH_MD5_SIZE];
paul718e3742002-12-13 20:15:29 +0000329 struct crypt_key *ck;
paul718e3742002-12-13 20:15:29 +0000330 struct ospf_neighbor *nbr;
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400331 u_int16_t length = ntohs (ospfh->length);
paul718e3742002-12-13 20:15:29 +0000332
paul718e3742002-12-13 20:15:29 +0000333 /* Get secret key. */
334 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
335 ospfh->u.crypt.key_id);
336 if (ck == NULL)
337 {
338 zlog_warn ("interface %s: ospf_check_md5 no key %d",
339 IF_NAME (oi), ospfh->u.crypt.key_id);
340 return 0;
341 }
342
343 /* check crypto seqnum. */
344 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
345
346 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
347 {
348 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
349 IF_NAME (oi),
350 ntohl(ospfh->u.crypt.crypt_seqnum),
351 ntohl(nbr->crypt_seqnum));
352 return 0;
353 }
354
355 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000356 memset(&ctx, 0, sizeof(ctx));
357 MD5Init(&ctx);
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400358 MD5Update(&ctx, ospfh, length);
vincentc1a03d42005-09-28 15:47:44 +0000359 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
360 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000361
362 /* compare the two */
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400363 if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE))
paul718e3742002-12-13 20:15:29 +0000364 {
365 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
366 IF_NAME (oi));
367 return 0;
368 }
369
370 /* save neighbor's crypt_seqnum */
371 if (nbr)
372 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
373 return 1;
374}
375
376/* This function is called from ospf_write(), it will detect the
377 authentication scheme and if it is MD5, it will change the sequence
378 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000379static int
paul718e3742002-12-13 20:15:29 +0000380ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
381{
382 struct ospf_header *ospfh;
383 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000384 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000385 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000386 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000387 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000388 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000389
390 ibuf = STREAM_DATA (op->s);
391 ospfh = (struct ospf_header *) ibuf;
392
393 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
394 return 0;
395
396 /* We do this here so when we dup a packet, we don't have to
Paul Jakma2518efd2006-08-27 06:49:29 +0000397 waste CPU rewriting other headers.
398
399 Note that quagga_time /deliberately/ is not used here */
paul9483e152002-12-13 20:55:25 +0000400 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000401 if (t > oi->crypt_seqnum)
402 oi->crypt_seqnum = t;
403 else
404 oi->crypt_seqnum++;
405
paul9483e152002-12-13 20:55:25 +0000406 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000407
408 /* Get MD5 Authentication key from auth_key list. */
409 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000410 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000411 else
412 {
paul1eb8ef22005-04-07 07:30:20 +0000413 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000414 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000415 }
416
417 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000418 memset(&ctx, 0, sizeof(ctx));
419 MD5Init(&ctx);
420 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
421 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
422 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000423
424 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000425 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000426
427 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000428 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
429
paul37163d62003-02-03 18:40:56 +0000430 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000431 /* XXX size_t */
432 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
433 (u_long)stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000434
435 return OSPF_AUTH_MD5_SIZE;
436}
437
438
paul4dadc292005-05-06 21:37:42 +0000439static int
paul718e3742002-12-13 20:15:29 +0000440ospf_ls_req_timer (struct thread *thread)
441{
442 struct ospf_neighbor *nbr;
443
444 nbr = THREAD_ARG (thread);
445 nbr->t_ls_req = NULL;
446
447 /* Send Link State Request. */
448 if (ospf_ls_request_count (nbr))
449 ospf_ls_req_send (nbr);
450
451 /* Set Link State Request retransmission timer. */
452 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
453
454 return 0;
455}
456
457void
458ospf_ls_req_event (struct ospf_neighbor *nbr)
459{
460 if (nbr->t_ls_req)
461 {
462 thread_cancel (nbr->t_ls_req);
463 nbr->t_ls_req = NULL;
464 }
465 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
466}
467
468/* Cyclic timer function. Fist registered in ospf_nbr_new () in
469 ospf_neighbor.c */
470int
471ospf_ls_upd_timer (struct thread *thread)
472{
473 struct ospf_neighbor *nbr;
474
475 nbr = THREAD_ARG (thread);
476 nbr->t_ls_upd = NULL;
477
478 /* Send Link State Update. */
479 if (ospf_ls_retransmit_count (nbr) > 0)
480 {
hasso52dc7ee2004-09-23 19:18:23 +0000481 struct list *update;
paul718e3742002-12-13 20:15:29 +0000482 struct ospf_lsdb *lsdb;
483 int i;
paul718e3742002-12-13 20:15:29 +0000484 int retransmit_interval;
485
paul718e3742002-12-13 20:15:29 +0000486 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
487
488 lsdb = &nbr->ls_rxmt;
489 update = list_new ();
490
491 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
492 {
493 struct route_table *table = lsdb->type[i].db;
494 struct route_node *rn;
495
496 for (rn = route_top (table); rn; rn = route_next (rn))
497 {
498 struct ospf_lsa *lsa;
499
500 if ((lsa = rn->info) != NULL)
501 /* Don't retransmit an LSA if we received it within
502 the last RxmtInterval seconds - this is to allow the
503 neighbour a chance to acknowledge the LSA as it may
504 have ben just received before the retransmit timer
505 fired. This is a small tweak to what is in the RFC,
506 but it will cut out out a lot of retransmit traffic
507 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000508 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000509 int2tv (retransmit_interval)) >= 0)
510 listnode_add (update, rn->info);
511 }
512 }
513
514 if (listcount (update) > 0)
515 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
516 list_delete (update);
517 }
518
519 /* Set LS Update retransmission timer. */
520 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
521
522 return 0;
523}
524
525int
526ospf_ls_ack_timer (struct thread *thread)
527{
528 struct ospf_interface *oi;
529
530 oi = THREAD_ARG (thread);
531 oi->t_ls_ack = NULL;
532
533 /* Send Link State Acknowledgment. */
534 if (listcount (oi->ls_ack) > 0)
535 ospf_ls_ack_send_delayed (oi);
536
537 /* Set LS Ack timer. */
538 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
539
540 return 0;
541}
542
paul0bfeca32004-09-24 08:07:54 +0000543#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000544static void
paul6a99f832004-09-27 12:56:30 +0000545ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000546 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000547 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000548{
549#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000550 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000551 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000552 int ret;
paul0bfeca32004-09-24 08:07:54 +0000553
554 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000555 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000556
557 /* we can but try.
558 *
559 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
560 * well as the IP_MF flag, making this all quite pointless.
561 *
562 * However, for a system on which IP_MF is left alone, and ip_id left
563 * alone or else which sets same ip_id for each fragment this might
564 * work, eg linux.
565 *
566 * XXX-TODO: It would be much nicer to have the kernel's use their
567 * existing fragmentation support to do this for us. Bugs/RFEs need to
568 * be raised against the various kernels.
569 */
570
571 /* set More Frag */
572 iph->ip_off |= IP_MF;
573
574 /* ip frag offset is expressed in units of 8byte words */
575 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
576
paul62d8e962004-11-02 20:26:45 +0000577 iovp = &msg->msg_iov[1];
578
paul0bfeca32004-09-24 08:07:54 +0000579 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
580 > maxdatasize )
581 {
582 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000583 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
584 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000585 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000586
paul18b12c32004-10-05 14:38:29 +0000587 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000588
paul6a99f832004-09-27 12:56:30 +0000589 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000590
paul18b12c32004-10-05 14:38:29 +0000591 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000592
593 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000594 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000595 " id %d, off %d, len %d, mtu %u failed with %s",
596 inet_ntoa (iph->ip_dst),
597 iph->ip_id,
598 iph->ip_off,
599 iph->ip_len,
600 mtu,
601 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000602
paul37ccfa32004-10-31 11:24:51 +0000603 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
604 {
ajs2a42e282004-12-08 18:43:03 +0000605 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000606 iph->ip_id, iph->ip_off, iph->ip_len,
607 inet_ntoa (iph->ip_dst));
608 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
609 {
ajs2a42e282004-12-08 18:43:03 +0000610 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000611 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000612 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000613 }
614 }
615
paul0bfeca32004-09-24 08:07:54 +0000616 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000617 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000618 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000619 }
620
621 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000622 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
623 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000624 iph->ip_off &= (~IP_MF);
625}
626#endif /* WANT_OSPF_WRITE_FRAGMENT */
627
ajs5dcbdf82005-03-29 16:13:49 +0000628static int
paul718e3742002-12-13 20:15:29 +0000629ospf_write (struct thread *thread)
630{
paul68980082003-03-25 05:07:42 +0000631 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000632 struct ospf_interface *oi;
633 struct ospf_packet *op;
634 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000635 struct ip iph;
636 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000637 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000638 u_char type;
639 int ret;
640 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000641 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000642#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000643 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000644#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000645 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000646#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000647
paul68980082003-03-25 05:07:42 +0000648 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000649
paul68980082003-03-25 05:07:42 +0000650 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000651 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000652 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000653 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000654
655#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000656 /* seed ipid static with low order bits of time */
657 if (ipid == 0)
658 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000659#endif /* WANT_OSPF_WRITE_FRAGMENT */
660
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000661 /* convenience - max OSPF data per packet,
662 * and reliability - not more data, than our
663 * socket can accept
664 */
665 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
666 sizeof (struct ip);
paul68b73392004-09-12 14:21:37 +0000667
paul718e3742002-12-13 20:15:29 +0000668 /* Get one packet from queue. */
669 op = ospf_fifo_head (oi->obuf);
670 assert (op);
671 assert (op->length >= OSPF_HEADER_SIZE);
672
paul68980082003-03-25 05:07:42 +0000673 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
674 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000675 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
676
paul718e3742002-12-13 20:15:29 +0000677 /* Rewrite the md5 signature & update the seq */
678 ospf_make_md5_digest (oi, op);
679
paul37ccfa32004-10-31 11:24:51 +0000680 /* Retrieve OSPF packet type. */
681 stream_set_getp (op->s, 1);
682 type = stream_getc (op->s);
683
paul68b73392004-09-12 14:21:37 +0000684 /* reset get pointer */
685 stream_set_getp (op->s, 0);
686
687 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000688 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000689
paul718e3742002-12-13 20:15:29 +0000690 sa_dst.sin_family = AF_INET;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000691#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +0000692 sa_dst.sin_len = sizeof(sa_dst);
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000693#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +0000694 sa_dst.sin_addr = op->dst;
695 sa_dst.sin_port = htons (0);
696
697 /* Set DONTROUTE flag if dst is unicast. */
698 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
699 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
700 flags = MSG_DONTROUTE;
701
paul68b73392004-09-12 14:21:37 +0000702 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
703 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000704 if ( sizeof (struct ip)
705 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000706 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
707
paul718e3742002-12-13 20:15:29 +0000708 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000709 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000710 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000711
David BÉRARD0150c9c2010-05-11 10:17:53 +0200712#if defined(__DragonFly__)
713 /*
714 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
715 */
716 iph.ip_len = htons(iph.ip_len);
717#endif
718
paul0bfeca32004-09-24 08:07:54 +0000719#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000720 /* XXX-MT: not thread-safe at all..
721 * XXX: this presumes this is only programme sending OSPF packets
722 * otherwise, no guarantee ipid will be unique
723 */
724 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000725#endif /* WANT_OSPF_WRITE_FRAGMENT */
726
paul718e3742002-12-13 20:15:29 +0000727 iph.ip_off = 0;
728 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
729 iph.ip_ttl = OSPF_VL_IP_TTL;
730 else
731 iph.ip_ttl = OSPF_IP_TTL;
732 iph.ip_p = IPPROTO_OSPFIGP;
733 iph.ip_sum = 0;
734 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
735 iph.ip_dst.s_addr = op->dst.s_addr;
736
737 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000738 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000739 msg.msg_namelen = sizeof (sa_dst);
740 msg.msg_iov = iov;
741 msg.msg_iovlen = 2;
742 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000743 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
744 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000745 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000746
747 /* Sadly we can not rely on kernels to fragment packets because of either
748 * IP_HDRINCL and/or multicast destination being set.
749 */
paul0bfeca32004-09-24 08:07:54 +0000750#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000751 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000752 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
753 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000754#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000755
756 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000757 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000758 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000759 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000760
761 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000762 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000763 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000764 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000765 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000766
paul718e3742002-12-13 20:15:29 +0000767 /* Show debug sending packet. */
768 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
769 {
770 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
771 {
ajs2a42e282004-12-08 18:43:03 +0000772 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000773 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000774 stream_set_getp (op->s, 0);
775 ospf_packet_dump (op->s);
776 }
777
ajs2a42e282004-12-08 18:43:03 +0000778 zlog_debug ("%s sent to [%s] via [%s].",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400779 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
paul718e3742002-12-13 20:15:29 +0000780 IF_NAME (oi));
781
782 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000783 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000784 }
785
786 /* Now delete packet from queue. */
787 ospf_packet_delete (oi);
788
789 if (ospf_fifo_head (oi->obuf) == NULL)
790 {
791 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000792 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000793 }
794
795 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000796 if (!list_isempty (ospf->oi_write_q))
797 ospf->t_write =
798 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000799
800 return 0;
801}
802
803/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000804static void
paul718e3742002-12-13 20:15:29 +0000805ospf_hello (struct ip *iph, struct ospf_header *ospfh,
806 struct stream * s, struct ospf_interface *oi, int size)
807{
808 struct ospf_hello *hello;
809 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000810 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000811 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000812
813 /* increment statistics. */
814 oi->hello_in++;
815
816 hello = (struct ospf_hello *) STREAM_PNT (s);
817
818 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000819 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000820 {
821 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
822 {
ajs2a42e282004-12-08 18:43:03 +0000823 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000824 "dropping.",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400825 LOOKUP (ospf_packet_type_str, ospfh->type),
pauld3241812003-09-29 12:42:39 +0000826 inet_ntoa (iph->ip_src));
827 }
828 return;
829 }
paul718e3742002-12-13 20:15:29 +0000830
paul718e3742002-12-13 20:15:29 +0000831 /* get neighbor prefix. */
832 p.family = AF_INET;
833 p.prefixlen = ip_masklen (hello->network_mask);
834 p.u.prefix4 = iph->ip_src;
835
836 /* Compare network mask. */
837 /* Checking is ignored for Point-to-Point and Virtual link. */
838 if (oi->type != OSPF_IFTYPE_POINTOPOINT
839 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
840 if (oi->address->prefixlen != p.prefixlen)
841 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000842 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
843 inet_ntoa(ospfh->router_id), IF_NAME(oi),
844 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000845 return;
846 }
847
paul718e3742002-12-13 20:15:29 +0000848 /* Compare Router Dead Interval. */
849 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
850 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000851 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
852 "(expected %u, but received %u).",
853 inet_ntoa(ospfh->router_id),
854 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000855 return;
856 }
857
paulf9ad9372005-10-21 00:45:17 +0000858 /* Compare Hello Interval - ignored if fast-hellos are set. */
859 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
860 {
861 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
862 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000863 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
864 "(expected %u, but received %u).",
865 inet_ntoa(ospfh->router_id),
866 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000867 return;
868 }
869 }
870
paul718e3742002-12-13 20:15:29 +0000871 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000872 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000873 inet_ntoa (ospfh->router_id),
874 ospf_options_dump (hello->options));
875
876 /* Compare options. */
877#define REJECT_IF_TBIT_ON 1 /* XXX */
878#ifdef REJECT_IF_TBIT_ON
879 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
880 {
881 /*
882 * This router does not support non-zero TOS.
883 * Drop this Hello packet not to establish neighbor relationship.
884 */
885 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
886 inet_ntoa (ospfh->router_id));
887 return;
888 }
889#endif /* REJECT_IF_TBIT_ON */
890
891#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000892 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000893 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
894 {
895 /*
896 * This router does know the correct usage of O-bit
897 * the bit should be set in DD packet only.
898 */
899 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
900 inet_ntoa (ospfh->router_id));
901#ifdef STRICT_OBIT_USAGE_CHECK
902 return; /* Reject this packet. */
903#else /* STRICT_OBIT_USAGE_CHECK */
904 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
905#endif /* STRICT_OBIT_USAGE_CHECK */
906 }
907#endif /* HAVE_OPAQUE_LSA */
908
909 /* new for NSSA is to ensure that NP is on and E is off */
910
paul718e3742002-12-13 20:15:29 +0000911 if (oi->area->external_routing == OSPF_AREA_NSSA)
912 {
913 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
914 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
915 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
916 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
917 {
918 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
919 return;
920 }
921 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000922 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000923 }
924 else
paul718e3742002-12-13 20:15:29 +0000925 /* The setting of the E-bit found in the Hello Packet's Options
926 field must match this area's ExternalRoutingCapability A
927 mismatch causes processing to stop and the packet to be
928 dropped. The setting of the rest of the bits in the Hello
929 Packet's Options field should be ignored. */
930 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
931 CHECK_FLAG (hello->options, OSPF_OPTION_E))
932 {
ajs3aa8d5f2004-12-11 18:00:06 +0000933 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
934 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000935 return;
936 }
paul718e3742002-12-13 20:15:29 +0000937
pauld3f0d622004-05-05 15:27:15 +0000938 /* get neighbour struct */
939 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
940
941 /* neighbour must be valid, ospf_nbr_get creates if none existed */
942 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000943
944 old_state = nbr->state;
945
946 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000947 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000948
949 /* RFC2328 Section 9.5.1
950 If the router is not eligible to become Designated Router,
951 (snip) It must also send an Hello Packet in reply to an
952 Hello Packet received from any eligible neighbor (other than
953 the current Designated Router and Backup Designated Router). */
954 if (oi->type == OSPF_IFTYPE_NBMA)
955 if (PRIORITY(oi) == 0 && hello->priority > 0
956 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
957 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
958 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
959 OSPF_HELLO_REPLY_DELAY);
960
961 /* on NBMA network type, it happens to receive bidirectional Hello packet
962 without advance 1-Way Received event.
963 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
964 if (oi->type == OSPF_IFTYPE_NBMA &&
965 (old_state == NSM_Down || old_state == NSM_Attempt))
966 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000967 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000968 nbr->priority = hello->priority;
969 nbr->d_router = hello->d_router;
970 nbr->bd_router = hello->bd_router;
971 return;
972 }
973
paul68980082003-03-25 05:07:42 +0000974 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000975 size - OSPF_HELLO_MIN_SIZE))
976 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000977 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000978 nbr->options |= hello->options;
979 }
980 else
981 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000982 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000983 /* Set neighbor information. */
984 nbr->priority = hello->priority;
985 nbr->d_router = hello->d_router;
986 nbr->bd_router = hello->bd_router;
987 return;
988 }
989
990 /* If neighbor itself declares DR and no BDR exists,
991 cause event BackupSeen */
992 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
993 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
994 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
995
996 /* neighbor itself declares BDR. */
997 if (oi->state == ISM_Waiting &&
998 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
999 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
1000
1001 /* had not previously. */
1002 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
1003 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
1004 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
1005 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
1006 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1007
1008 /* had not previously. */
1009 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
1010 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
1011 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
1012 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
1013 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1014
1015 /* Neighbor priority check. */
1016 if (nbr->priority >= 0 && nbr->priority != hello->priority)
1017 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1018
1019 /* Set neighbor information. */
1020 nbr->priority = hello->priority;
1021 nbr->d_router = hello->d_router;
1022 nbr->bd_router = hello->bd_router;
1023}
1024
1025/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +00001026static void
paul718e3742002-12-13 20:15:29 +00001027ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1028 struct ospf_db_desc *dd)
1029{
1030 nbr->last_recv.flags = dd->flags;
1031 nbr->last_recv.options = dd->options;
1032 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1033}
1034
1035/* Process rest of DD packet. */
1036static void
1037ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1038 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1039 u_int16_t size)
1040{
1041 struct ospf_lsa *new, *find;
1042 struct lsa_header *lsah;
1043
paul9985f832005-02-09 15:51:56 +00001044 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001045 for (size -= OSPF_DB_DESC_MIN_SIZE;
1046 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1047 {
1048 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001049 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001050
1051 /* Unknown LS type. */
1052 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1053 {
ajsbec595a2004-11-30 22:38:43 +00001054 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001055 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1056 return;
1057 }
1058
1059#ifdef HAVE_OPAQUE_LSA
1060 if (IS_OPAQUE_LSA (lsah->type)
1061 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1062 {
1063 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1064 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1065 return;
1066 }
1067#endif /* HAVE_OPAQUE_LSA */
1068
1069 switch (lsah->type)
1070 {
1071 case OSPF_AS_EXTERNAL_LSA:
1072#ifdef HAVE_OPAQUE_LSA
1073 case OSPF_OPAQUE_AS_LSA:
1074#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001075 /* Check for stub area. Reject if AS-External from stub but
1076 allow if from NSSA. */
1077 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001078 {
1079 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1080 lsah->type, inet_ntoa (lsah->id),
1081 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1082 "STUB" : "NSSA");
1083 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1084 return;
1085 }
1086 break;
1087 default:
1088 break;
1089 }
1090
1091 /* Create LS-request object. */
1092 new = ospf_ls_request_new (lsah);
1093
1094 /* Lookup received LSA, then add LS request list. */
1095 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001096
1097 /* ospf_lsa_more_recent is fine with NULL pointers */
1098 switch (ospf_lsa_more_recent (find, new))
1099 {
1100 case -1:
1101 /* Neighbour has a more recent LSA, we must request it */
1102 ospf_ls_request_add (nbr, new);
1103 case 0:
1104 /* If we have a copy of this LSA, it's either less recent
1105 * and we're requesting it from neighbour (the case above), or
1106 * it's as recent and we both have same copy (this case).
1107 *
1108 * In neither of these two cases is there any point in
1109 * describing our copy of the LSA to the neighbour in a
1110 * DB-Summary packet, if we're still intending to do so.
1111 *
1112 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1113 * backward compatible optimisation to OSPF DB Exchange /
1114 * DB Description process implemented here.
1115 */
1116 if (find)
1117 ospf_lsdb_delete (&nbr->db_sum, find);
1118 ospf_lsa_discard (new);
1119 break;
1120 default:
1121 /* We have the more recent copy, nothing specific to do:
1122 * - no need to request neighbours stale copy
1123 * - must leave DB summary list copy alone
1124 */
1125 if (IS_DEBUG_OSPF_EVENT)
1126 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1127 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1128 ospf_lsa_discard (new);
1129 }
paul718e3742002-12-13 20:15:29 +00001130 }
1131
1132 /* Master */
1133 if (IS_SET_DD_MS (nbr->dd_flags))
1134 {
1135 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001136
1137 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001138 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1139 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1140 else
paul718e3742002-12-13 20:15:29 +00001141 ospf_db_desc_send (nbr);
1142 }
1143 /* Slave */
1144 else
1145 {
1146 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1147
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001148 /* Send DD packet in reply.
1149 *
1150 * Must be done to acknowledge the Master's DD, regardless of
1151 * whether we have more LSAs ourselves to describe.
1152 *
1153 * This function will clear the 'More' bit, if after this DD
1154 * we have no more LSAs to describe to the master..
1155 */
paul718e3742002-12-13 20:15:29 +00001156 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001157
1158 /* Slave can raise ExchangeDone now, if master is also done */
1159 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1160 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001161 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001162
paul718e3742002-12-13 20:15:29 +00001163 /* Save received neighbor values from DD. */
1164 ospf_db_desc_save_current (nbr, dd);
1165}
1166
paul4dadc292005-05-06 21:37:42 +00001167static int
paul718e3742002-12-13 20:15:29 +00001168ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1169{
1170 /* Is DD duplicated? */
1171 if (dd->options == nbr->last_recv.options &&
1172 dd->flags == nbr->last_recv.flags &&
1173 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1174 return 1;
1175
1176 return 0;
1177}
1178
1179/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001180static void
paul718e3742002-12-13 20:15:29 +00001181ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1182 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1183{
1184 struct ospf_db_desc *dd;
1185 struct ospf_neighbor *nbr;
1186
1187 /* Increment statistics. */
1188 oi->db_desc_in++;
1189
1190 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001191
pauld3f0d622004-05-05 15:27:15 +00001192 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001193 if (nbr == NULL)
1194 {
1195 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1196 inet_ntoa (ospfh->router_id));
1197 return;
1198 }
1199
1200 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001201 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1202 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001203 {
ajs3aa8d5f2004-12-11 18:00:06 +00001204 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1205 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1206 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001207 return;
1208 }
1209
pauld363df22003-06-19 00:26:34 +00001210 /*
1211 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1212 * required. In fact at least JunOS sends DD packets with P bit clear.
1213 * Until proper solution is developped, this hack should help.
1214 *
1215 * Update: According to the RFCs, N bit is specified /only/ for Hello
1216 * options, unfortunately its use in DD options is not specified. Hence some
1217 * implementations follow E-bit semantics and set it in DD options, and some
1218 * treat it as unspecified and hence follow the directive "default for
1219 * options is clear", ie unset.
1220 *
1221 * Reset the flag, as ospfd follows E-bit semantics.
1222 */
1223 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1224 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1225 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1226 {
1227 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001228 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001229 inet_ntoa (nbr->router_id) );
1230 SET_FLAG (dd->options, OSPF_OPTION_NP);
1231 }
pauld363df22003-06-19 00:26:34 +00001232
paul718e3742002-12-13 20:15:29 +00001233#ifdef REJECT_IF_TBIT_ON
1234 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1235 {
1236 /*
1237 * In Hello protocol, optional capability must have checked
1238 * to prevent this T-bit enabled router be my neighbor.
1239 */
1240 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1241 return;
1242 }
1243#endif /* REJECT_IF_TBIT_ON */
1244
1245#ifdef HAVE_OPAQUE_LSA
1246 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001247 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001248 {
1249 /*
1250 * This node is not configured to handle O-bit, for now.
1251 * Clear it to ignore unsupported capability proposed by neighbor.
1252 */
1253 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1254 }
1255#endif /* HAVE_OPAQUE_LSA */
1256
Paul Jakma57c5c652010-01-07 06:12:53 +00001257 /* Add event to thread. */
1258 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1259
paul718e3742002-12-13 20:15:29 +00001260 /* Process DD packet by neighbor status. */
1261 switch (nbr->state)
1262 {
1263 case NSM_Down:
1264 case NSM_Attempt:
1265 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001266 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001267 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001268 LOOKUP (ospf_nsm_state_msg, nbr->state));
1269 break;
1270 case NSM_Init:
1271 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1272 /* If the new state is ExStart, the processing of the current
1273 packet should then continue in this new state by falling
1274 through to case ExStart below. */
1275 if (nbr->state != NSM_ExStart)
1276 break;
1277 case NSM_ExStart:
1278 /* Initial DBD */
1279 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1280 (size == OSPF_DB_DESC_MIN_SIZE))
1281 {
paul68980082003-03-25 05:07:42 +00001282 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001283 {
1284 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001285 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001286 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001287 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001288
1289 /* Reset I/MS */
1290 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001291 }
1292 else
1293 {
1294 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001295 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001296 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001297 break;
1298 }
1299 }
1300 /* Ack from the Slave */
1301 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1302 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001303 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001304 {
ajs17eaa722004-12-29 21:04:48 +00001305 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001306 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001307 /* Reset I, leaving MS */
1308 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001309 }
1310 else
1311 {
ajs3aa8d5f2004-12-11 18:00:06 +00001312 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1313 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001314 break;
1315 }
1316
1317 /* This is where the real Options are saved */
1318 nbr->options = dd->options;
1319
1320#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001321 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001322 {
1323 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001324 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001325 inet_ntoa (nbr->router_id),
1326 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1327
1328 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1329 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1330 {
paul6d452762005-11-03 11:15:44 +00001331 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1332 "Opaque-LSAs cannot be reliably advertised "
1333 "in this network.",
1334 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001335 /* This situation is undesirable, but not a real error. */
1336 }
1337 }
1338#endif /* HAVE_OPAQUE_LSA */
1339
1340 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1341
1342 /* continue processing rest of packet. */
1343 ospf_db_desc_proc (s, oi, nbr, dd, size);
1344 break;
1345 case NSM_Exchange:
1346 if (ospf_db_desc_is_dup (dd, nbr))
1347 {
1348 if (IS_SET_DD_MS (nbr->dd_flags))
1349 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001350 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001351 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001352 else
1353 /* Slave: cause to retransmit the last Database Description. */
1354 {
paul6d452762005-11-03 11:15:44 +00001355 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001356 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001357 ospf_db_desc_resend (nbr);
1358 }
1359 break;
1360 }
1361
1362 /* Otherwise DD packet should be checked. */
1363 /* Check Master/Slave bit mismatch */
1364 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1365 {
ajs3aa8d5f2004-12-11 18:00:06 +00001366 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1367 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001368 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1369 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001370 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001371 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001372 break;
1373 }
1374
1375 /* Check initialize bit is set. */
1376 if (IS_SET_DD_I (dd->flags))
1377 {
paul6d452762005-11-03 11:15:44 +00001378 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001379 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001380 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1381 break;
1382 }
1383
1384 /* Check DD Options. */
1385 if (dd->options != nbr->options)
1386 {
1387#ifdef ORIGINAL_CODING
1388 /* Save the new options for debugging */
1389 nbr->options = dd->options;
1390#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001391 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1392 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001393 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1394 break;
1395 }
1396
1397 /* Check DD sequence number. */
1398 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1399 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1400 (!IS_SET_DD_MS (nbr->dd_flags) &&
1401 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1402 {
ajs3aa8d5f2004-12-11 18:00:06 +00001403 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1404 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001405 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1406 break;
1407 }
1408
1409 /* Continue processing rest of packet. */
1410 ospf_db_desc_proc (s, oi, nbr, dd, size);
1411 break;
1412 case NSM_Loading:
1413 case NSM_Full:
1414 if (ospf_db_desc_is_dup (dd, nbr))
1415 {
1416 if (IS_SET_DD_MS (nbr->dd_flags))
1417 {
1418 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001419 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1420 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001421 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001422 break;
1423 }
1424 else
1425 {
1426 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001427 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001428 t = tv_sub (now, nbr->last_send_ts);
1429 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1430 {
1431 /* In states Loading and Full the slave must resend
1432 its last Database Description packet in response to
1433 duplicate Database Description packets received
1434 from the master. For this reason the slave must
1435 wait RouterDeadInterval seconds before freeing the
1436 last Database Description packet. Reception of a
1437 Database Description packet from the master after
1438 this interval will generate a SeqNumberMismatch
1439 neighbor event. RFC2328 Section 10.8 */
1440 ospf_db_desc_resend (nbr);
1441 break;
1442 }
1443 }
1444 }
1445
1446 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1447 break;
1448 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001449 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1450 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001451 break;
1452 }
1453}
1454
1455#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1456
1457/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001458static void
paul718e3742002-12-13 20:15:29 +00001459ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1460 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1461{
1462 struct ospf_neighbor *nbr;
1463 u_int32_t ls_type;
1464 struct in_addr ls_id;
1465 struct in_addr adv_router;
1466 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001467 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001468 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001469
1470 /* Increment statistics. */
1471 oi->ls_req_in++;
1472
pauld3f0d622004-05-05 15:27:15 +00001473 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001474 if (nbr == NULL)
1475 {
1476 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1477 inet_ntoa (ospfh->router_id));
1478 return;
1479 }
1480
Paul Jakma57c5c652010-01-07 06:12:53 +00001481 /* Add event to thread. */
1482 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1483
paul718e3742002-12-13 20:15:29 +00001484 /* Neighbor State should be Exchange or later. */
1485 if (nbr->state != NSM_Exchange &&
1486 nbr->state != NSM_Loading &&
1487 nbr->state != NSM_Full)
1488 {
ajsbec595a2004-11-30 22:38:43 +00001489 zlog_warn ("Link State Request received from %s: "
1490 "Neighbor state is %s, packet discarded.",
1491 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001492 LOOKUP (ospf_nsm_state_msg, nbr->state));
1493 return;
1494 }
1495
1496 /* Send Link State Update for ALL requested LSAs. */
1497 ls_upd = list_new ();
1498 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1499
1500 while (size >= OSPF_LSA_KEY_SIZE)
1501 {
1502 /* Get one slice of Link State Request. */
1503 ls_type = stream_getl (s);
1504 ls_id.s_addr = stream_get_ipv4 (s);
1505 adv_router.s_addr = stream_get_ipv4 (s);
1506
1507 /* Verify LSA type. */
1508 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1509 {
1510 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1511 list_delete (ls_upd);
1512 return;
1513 }
1514
1515 /* Search proper LSA in LSDB. */
1516 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1517 if (find == NULL)
1518 {
1519 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1520 list_delete (ls_upd);
1521 return;
1522 }
1523
gdt86f1fd92005-01-10 14:20:43 +00001524 /* Packet overflows MTU size, send immediately. */
1525 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001526 {
1527 if (oi->type == OSPF_IFTYPE_NBMA)
1528 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1529 else
1530 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1531
1532 /* Only remove list contents. Keep ls_upd. */
1533 list_delete_all_node (ls_upd);
1534
1535 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1536 }
1537
1538 /* Append LSA to update list. */
1539 listnode_add (ls_upd, find);
1540 length += ntohs (find->data->length);
1541
1542 size -= OSPF_LSA_KEY_SIZE;
1543 }
1544
1545 /* Send rest of Link State Update. */
1546 if (listcount (ls_upd) > 0)
1547 {
1548 if (oi->type == OSPF_IFTYPE_NBMA)
1549 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1550 else
1551 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1552
1553 list_delete (ls_upd);
1554 }
1555 else
1556 list_free (ls_upd);
1557}
1558
1559/* Get the list of LSAs from Link State Update packet.
1560 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001561static struct list *
paul718e3742002-12-13 20:15:29 +00001562ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1563 struct ospf_interface *oi, size_t size)
1564{
1565 u_int16_t count, sum;
1566 u_int32_t length;
1567 struct lsa_header *lsah;
1568 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001569 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001570
1571 lsas = list_new ();
1572
1573 count = stream_getl (s);
1574 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1575
1576 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001577 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001578 {
1579 lsah = (struct lsa_header *) STREAM_PNT (s);
1580 length = ntohs (lsah->length);
1581
1582 if (length > size)
1583 {
1584 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1585 break;
1586 }
1587
1588 /* Validate the LSA's LS checksum. */
1589 sum = lsah->checksum;
1590 if (sum != ospf_lsa_checksum (lsah))
1591 {
Jaroslav Fojtik223da1a2011-12-11 18:22:16 +04001592 /* (bug #685) more details in a one-line message make it possible
1593 * to identify problem source on the one hand and to have a better
1594 * chance to compress repeated messages in syslog on the other */
1595 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1596 sum, lsah->checksum, inet_ntoa (lsah->id),
1597 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1598 inet_ntoa (lsah->adv_router));
paul718e3742002-12-13 20:15:29 +00001599 continue;
1600 }
1601
1602 /* Examine the LSA's LS type. */
1603 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1604 {
1605 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1606 continue;
1607 }
1608
1609 /*
1610 * What if the received LSA's age is greater than MaxAge?
1611 * Treat it as a MaxAge case -- endo.
1612 */
1613 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1614 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1615
1616#ifdef HAVE_OPAQUE_LSA
1617 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1618 {
1619#ifdef STRICT_OBIT_USAGE_CHECK
1620 if ((IS_OPAQUE_LSA(lsah->type) &&
1621 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1622 || (! IS_OPAQUE_LSA(lsah->type) &&
1623 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1624 {
1625 /*
1626 * This neighbor must know the exact usage of O-bit;
1627 * the bit will be set in Type-9,10,11 LSAs only.
1628 */
1629 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1630 continue;
1631 }
1632#endif /* STRICT_OBIT_USAGE_CHECK */
1633
1634 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1635 if (lsah->type == OSPF_OPAQUE_AS_LSA
1636 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1637 {
1638 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001639 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 +00001640 continue;
1641 }
1642 }
1643 else if (IS_OPAQUE_LSA(lsah->type))
1644 {
1645 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1646 continue;
1647 }
1648#endif /* HAVE_OPAQUE_LSA */
1649
1650 /* Create OSPF LSA instance. */
1651 lsa = ospf_lsa_new ();
1652
1653 /* We may wish to put some error checking if type NSSA comes in
1654 and area not in NSSA mode */
1655 switch (lsah->type)
1656 {
1657 case OSPF_AS_EXTERNAL_LSA:
1658#ifdef HAVE_OPAQUE_LSA
1659 case OSPF_OPAQUE_AS_LSA:
1660 lsa->area = NULL;
1661 break;
1662 case OSPF_OPAQUE_LINK_LSA:
1663 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1664 /* Fallthrough */
1665#endif /* HAVE_OPAQUE_LSA */
1666 default:
1667 lsa->area = oi->area;
1668 break;
1669 }
1670
1671 lsa->data = ospf_lsa_data_new (length);
1672 memcpy (lsa->data, lsah, length);
1673
1674 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001675 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001676 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1677 listnode_add (lsas, lsa);
1678 }
1679
1680 return lsas;
1681}
1682
1683/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001684static void
hasso52dc7ee2004-09-23 19:18:23 +00001685ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001686{
paul1eb8ef22005-04-07 07:30:20 +00001687 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001688 struct ospf_lsa *lsa;
1689
paul1eb8ef22005-04-07 07:30:20 +00001690 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1691 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001692
1693 list_delete (lsas);
1694}
1695
1696/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001697static void
paul718e3742002-12-13 20:15:29 +00001698ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1699 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1700{
1701 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001702 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001703 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001704 struct ospf_lsa *lsa = NULL;
1705 /* unsigned long ls_req_found = 0; */
1706
1707 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1708
1709 /* Increment statistics. */
1710 oi->ls_upd_in++;
1711
1712 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001713 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001714 if (nbr == NULL)
1715 {
1716 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1717 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1718 return;
1719 }
1720
Paul Jakma57c5c652010-01-07 06:12:53 +00001721 /* Add event to thread. */
1722 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1723
paul718e3742002-12-13 20:15:29 +00001724 /* Check neighbor state. */
1725 if (nbr->state < NSM_Exchange)
1726 {
ajs3aa8d5f2004-12-11 18:00:06 +00001727 zlog_warn ("Link State Update: "
1728 "Neighbor[%s] state %s is less than Exchange",
1729 inet_ntoa (ospfh->router_id),
1730 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001731 return;
1732 }
1733
1734 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1735 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1736 * of section 13.
1737 */
1738 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1739
1740#ifdef HAVE_OPAQUE_LSA
1741 /*
paul718e3742002-12-13 20:15:29 +00001742 * If self-originated Opaque-LSAs that have flooded before restart
1743 * are contained in the received LSUpd message, corresponding LSReq
1744 * messages to be sent may have to be modified.
1745 * To eliminate possible race conditions such that flushing and normal
1746 * updating for the same LSA would take place alternately, this trick
1747 * must be done before entering to the loop below.
1748 */
paul69310a62005-05-11 18:09:59 +00001749 /* XXX: Why is this Opaque specific? Either our core code is deficient
1750 * and this should be fixed generally, or Opaque is inventing strawman
1751 * problems */
paul718e3742002-12-13 20:15:29 +00001752 ospf_opaque_adjust_lsreq (nbr, lsas);
1753#endif /* HAVE_OPAQUE_LSA */
1754
1755#define DISCARD_LSA(L,N) {\
1756 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001757 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 +00001758 ospf_lsa_discard (L); \
1759 continue; }
1760
1761 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001762 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001763 {
1764 struct ospf_lsa *ls_ret, *current;
1765 int ret = 1;
1766
paul718e3742002-12-13 20:15:29 +00001767 if (IS_DEBUG_OSPF_NSSA)
1768 {
1769 char buf1[INET_ADDRSTRLEN];
1770 char buf2[INET_ADDRSTRLEN];
1771 char buf3[INET_ADDRSTRLEN];
1772
ajs2a42e282004-12-08 18:43:03 +00001773 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001774 lsa->data->type,
1775 inet_ntop (AF_INET, &ospfh->router_id,
1776 buf1, INET_ADDRSTRLEN),
1777 inet_ntop (AF_INET, &lsa->data->id,
1778 buf2, INET_ADDRSTRLEN),
1779 inet_ntop (AF_INET, &lsa->data->adv_router,
1780 buf3, INET_ADDRSTRLEN));
1781 }
paul718e3742002-12-13 20:15:29 +00001782
1783 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1784
1785 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1786
1787 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1788
1789 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1790
1791 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1792
1793 /* Do take in Type-7's if we are an NSSA */
1794
1795 /* If we are also an ABR, later translate them to a Type-5 packet */
1796
1797 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1798 translate them to a separate Type-5 packet. */
1799
1800 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1801 /* Reject from STUB or NSSA */
1802 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1803 {
paul718e3742002-12-13 20:15:29 +00001804 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001805 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001806 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001807 }
1808
paul718e3742002-12-13 20:15:29 +00001809 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1810 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1811 {
paul718e3742002-12-13 20:15:29 +00001812 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001813 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001814 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001815 }
paul718e3742002-12-13 20:15:29 +00001816
1817 /* Find the LSA in the current database. */
1818
1819 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1820
1821 /* If the LSA's LS age is equal to MaxAge, and there is currently
1822 no instance of the LSA in the router's link state database,
1823 and none of router's neighbors are in states Exchange or Loading,
1824 then take the following actions. */
1825
1826 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001827 (ospf_nbr_count (oi, NSM_Exchange) +
1828 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001829 {
1830 /* Response Link State Acknowledgment. */
1831 ospf_ls_ack_send (nbr, lsa);
1832
1833 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001834 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1835 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001836 DISCARD_LSA (lsa, 3);
1837 }
1838
1839#ifdef HAVE_OPAQUE_LSA
1840 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001841 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001842 {
1843 /*
1844 * Even if initial flushing seems to be completed, there might
1845 * be a case that self-originated LSA with MaxAge still remain
1846 * in the routing domain.
1847 * Just send an LSAck message to cease retransmission.
1848 */
1849 if (IS_LSA_MAXAGE (lsa))
1850 {
1851 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1852 ospf_ls_ack_send (nbr, lsa);
1853 ospf_lsa_discard (lsa);
1854
1855 if (current != NULL && ! IS_LSA_MAXAGE (current))
1856 ospf_opaque_lsa_refresh_schedule (current);
1857 continue;
1858 }
1859
1860 /*
1861 * If an instance of self-originated Opaque-LSA is not found
1862 * in the LSDB, there are some possible cases here.
1863 *
1864 * 1) This node lost opaque-capability after restart.
1865 * 2) Else, a part of opaque-type is no more supported.
1866 * 3) Else, a part of opaque-id is no more supported.
1867 *
1868 * Anyway, it is still this node's responsibility to flush it.
1869 * Otherwise, the LSA instance remains in the routing domain
1870 * until its age reaches to MaxAge.
1871 */
paul69310a62005-05-11 18:09:59 +00001872 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001873 if (current == NULL)
1874 {
1875 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001876 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1877 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001878
1879 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001880
1881 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1882 ospf_ls_ack_send (nbr, lsa);
1883
paul718e3742002-12-13 20:15:29 +00001884 continue;
1885 }
1886 }
1887#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001888
hassocb05eb22004-02-11 21:10:19 +00001889 /* It might be happen that received LSA is self-originated network LSA, but
1890 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1891 * Link State ID is one of the router's own IP interface addresses but whose
1892 * Advertising Router is not equal to the router's own Router ID
1893 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1894 */
1895
1896 if(lsa->data->type == OSPF_NETWORK_LSA)
1897 {
paul1eb8ef22005-04-07 07:30:20 +00001898 struct listnode *oinode, *oinnode;
1899 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001900 int Flag = 0;
1901
paul1eb8ef22005-04-07 07:30:20 +00001902 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001903 {
hassocb05eb22004-02-11 21:10:19 +00001904 if(out_if == NULL)
1905 break;
1906
1907 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1908 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1909 {
1910 if(out_if->network_lsa_self)
1911 {
1912 ospf_lsa_flush_area(lsa,out_if->area);
1913 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001914 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001915 lsa, (int) lsa->data->type);
1916 ospf_lsa_discard (lsa);
1917 Flag = 1;
1918 }
1919 break;
1920 }
1921 }
1922 if(Flag)
1923 continue;
1924 }
paul718e3742002-12-13 20:15:29 +00001925
1926 /* (5) Find the instance of this LSA that is currently contained
1927 in the router's link state database. If there is no
1928 database copy, or the received LSA is more recent than
1929 the database copy the following steps must be performed. */
1930
1931 if (current == NULL ||
1932 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1933 {
1934 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001935 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001936 DISCARD_LSA (lsa, 4);
1937 continue;
1938 }
1939
1940 /* (6) Else, If there is an instance of the LSA on the sending
1941 neighbor's Link state request list, an error has occurred in
1942 the Database Exchange process. In this case, restart the
1943 Database Exchange process by generating the neighbor event
1944 BadLSReq for the sending neighbor and stop processing the
1945 Link State Update packet. */
1946
1947 if (ospf_ls_request_lookup (nbr, lsa))
1948 {
1949 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001950 zlog_warn("LSA[%s] instance exists on Link state request list",
1951 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001952
1953 /* Clean list of LSAs. */
1954 ospf_upd_list_clean (lsas);
1955 /* this lsa is not on lsas list already. */
1956 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001957 return;
1958 }
1959
1960 /* If the received LSA is the same instance as the database copy
1961 (i.e., neither one is more recent) the following two steps
1962 should be performed: */
1963
1964 if (ret == 0)
1965 {
1966 /* If the LSA is listed in the Link state retransmission list
1967 for the receiving adjacency, the router itself is expecting
1968 an acknowledgment for this LSA. The router should treat the
1969 received LSA as an acknowledgment by removing the LSA from
1970 the Link state retransmission list. This is termed an
1971 "implied acknowledgment". */
1972
1973 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1974
1975 if (ls_ret != NULL)
1976 {
1977 ospf_ls_retransmit_delete (nbr, ls_ret);
1978
1979 /* Delayed acknowledgment sent if advertisement received
1980 from Designated Router, otherwise do nothing. */
1981 if (oi->state == ISM_Backup)
1982 if (NBR_IS_DR (nbr))
1983 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1984
1985 DISCARD_LSA (lsa, 5);
1986 }
1987 else
1988 /* Acknowledge the receipt of the LSA by sending a
1989 Link State Acknowledgment packet back out the receiving
1990 interface. */
1991 {
1992 ospf_ls_ack_send (nbr, lsa);
1993 DISCARD_LSA (lsa, 6);
1994 }
1995 }
1996
1997 /* The database copy is more recent. If the database copy
1998 has LS age equal to MaxAge and LS sequence number equal to
1999 MaxSequenceNumber, simply discard the received LSA without
2000 acknowledging it. (In this case, the LSA's LS sequence number is
2001 wrapping, and the MaxSequenceNumber LSA must be completely
2002 flushed before any new LSA instance can be introduced). */
2003
2004 else if (ret > 0) /* Database copy is more recent */
2005 {
2006 if (IS_LSA_MAXAGE (current) &&
2007 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
2008 {
2009 DISCARD_LSA (lsa, 7);
2010 }
2011 /* Otherwise, as long as the database copy has not been sent in a
2012 Link State Update within the last MinLSArrival seconds, send the
2013 database copy back to the sending neighbor, encapsulated within
2014 a Link State Update Packet. The Link State Update Packet should
2015 be sent directly to the neighbor. In so doing, do not put the
2016 database copy of the LSA on the neighbor's link state
2017 retransmission list, and do not acknowledge the received (less
2018 recent) LSA instance. */
2019 else
2020 {
2021 struct timeval now;
2022
Paul Jakma2518efd2006-08-27 06:49:29 +00002023 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00002024
2025 if (tv_cmp (tv_sub (now, current->tv_orig),
Paul Jakma2c9f8e32010-01-11 16:22:12 +00002026 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
paul718e3742002-12-13 20:15:29 +00002027 /* Trap NSSA type later.*/
2028 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2029 DISCARD_LSA (lsa, 8);
2030 }
2031 }
2032 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002033#undef DISCARD_LSA
2034
paul718e3742002-12-13 20:15:29 +00002035 assert (listcount (lsas) == 0);
2036 list_delete (lsas);
2037}
2038
2039/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002040static void
paul718e3742002-12-13 20:15:29 +00002041ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2042 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2043{
2044 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002045
paul718e3742002-12-13 20:15:29 +00002046 /* increment statistics. */
2047 oi->ls_ack_in++;
2048
pauld3f0d622004-05-05 15:27:15 +00002049 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002050 if (nbr == NULL)
2051 {
2052 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2053 inet_ntoa (ospfh->router_id));
2054 return;
2055 }
2056
Paul Jakma57c5c652010-01-07 06:12:53 +00002057 /* Add event to thread. */
2058 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2059
paul718e3742002-12-13 20:15:29 +00002060 if (nbr->state < NSM_Exchange)
2061 {
ajs3aa8d5f2004-12-11 18:00:06 +00002062 zlog_warn ("Link State Acknowledgment: "
2063 "Neighbor[%s] state %s is less than Exchange",
2064 inet_ntoa (ospfh->router_id),
2065 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002066 return;
2067 }
paul69310a62005-05-11 18:09:59 +00002068
paul718e3742002-12-13 20:15:29 +00002069 while (size >= OSPF_LSA_HEADER_SIZE)
2070 {
2071 struct ospf_lsa *lsa, *lsr;
2072
2073 lsa = ospf_lsa_new ();
2074 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2075
2076 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2077 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002078 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002079
2080 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2081 {
2082 lsa->data = NULL;
2083 ospf_lsa_discard (lsa);
2084 continue;
2085 }
2086
2087 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2088
2089 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2090 {
2091#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002092 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002093 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002094#endif /* HAVE_OPAQUE_LSA */
2095
2096 ospf_ls_retransmit_delete (nbr, lsr);
2097 }
2098
2099 lsa->data = NULL;
2100 ospf_lsa_discard (lsa);
2101 }
2102
paul718e3742002-12-13 20:15:29 +00002103 return;
paul718e3742002-12-13 20:15:29 +00002104}
2105
ajs038163f2005-02-17 19:55:59 +00002106static struct stream *
ajs5c333492005-02-23 15:43:01 +00002107ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002108{
2109 int ret;
ajs5c333492005-02-23 15:43:01 +00002110 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002111 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002112 unsigned int ifindex = 0;
2113 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002114 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002115 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002116 struct msghdr msgh;
2117
paul68defd62004-09-27 07:27:13 +00002118 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002119 msgh.msg_iov = &iov;
2120 msgh.msg_iovlen = 1;
2121 msgh.msg_control = (caddr_t) buff;
2122 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002123
ajs5c333492005-02-23 15:43:01 +00002124 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2125 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002126 {
ajs5c333492005-02-23 15:43:01 +00002127 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2128 return NULL;
2129 }
paul69310a62005-05-11 18:09:59 +00002130 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002131 {
2132 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2133 "(ip header size is %u)",
2134 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002135 return NULL;
2136 }
paul18b12c32004-10-05 14:38:29 +00002137
ajs5c333492005-02-23 15:43:01 +00002138 /* Note that there should not be alignment problems with this assignment
2139 because this is at the beginning of the stream data buffer. */
2140 iph = (struct ip *) STREAM_DATA(ibuf);
2141 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002142
ajs5c333492005-02-23 15:43:01 +00002143 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002144
Dmitrij Tejblumde5ccb92011-12-12 20:30:10 +04002145#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
paul718e3742002-12-13 20:15:29 +00002146 /*
2147 * Kernel network code touches incoming IP header parameters,
2148 * before protocol specific processing.
2149 *
2150 * 1) Convert byteorder to host representation.
2151 * --> ip_len, ip_id, ip_off
2152 *
2153 * 2) Adjust ip_len to strip IP header size!
2154 * --> If user process receives entire IP packet via RAW
2155 * socket, it must consider adding IP header size to
2156 * the "ip_len" field of "ip" structure.
2157 *
2158 * For more details, see <netinet/ip_input.c>.
2159 */
ajs5c333492005-02-23 15:43:01 +00002160 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002161#endif
2162
David BÉRARD0150c9c2010-05-11 10:17:53 +02002163#if defined(__DragonFly__)
2164 /*
2165 * in DragonFly's raw socket, ip_len/ip_off are read
2166 * in network byte order.
2167 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2168 */
2169 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2170#endif
2171
paul863082d2004-08-19 04:43:43 +00002172 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002173
2174 *ifp = if_lookup_by_index (ifindex);
2175
2176 if (ret != ip_len)
2177 {
ajs5c333492005-02-23 15:43:01 +00002178 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2179 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002180 return NULL;
2181 }
2182
2183 return ibuf;
2184}
2185
paul4dadc292005-05-06 21:37:42 +00002186static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002187ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002188 struct ip *iph, struct ospf_header *ospfh)
2189{
2190 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002191 struct ospf_vl_data *vl_data;
2192 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002193 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002194
2195 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2196 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002197 return NULL;
paul718e3742002-12-13 20:15:29 +00002198
pauld3f0d622004-05-05 15:27:15 +00002199 /* look for local OSPF interface matching the destination
2200 * to determine Area ID. We presume therefore the destination address
2201 * is unique, or at least (for "unnumbered" links), not used in other
2202 * areas
2203 */
2204 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2205 iph->ip_dst)) == NULL)
2206 return NULL;
paul718e3742002-12-13 20:15:29 +00002207
paul1eb8ef22005-04-07 07:30:20 +00002208 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002209 {
paul020709f2003-04-04 02:44:16 +00002210 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002211 if (!vl_area)
2212 continue;
2213
2214 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2215 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2216 {
2217 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002218 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002219 IF_NAME (vl_data->vl_oi));
2220 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2221 {
2222 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002223 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002224 return NULL;
2225 }
2226
2227 return vl_data->vl_oi;
2228 }
2229 }
2230
2231 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002232 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002233
pauld3f0d622004-05-05 15:27:15 +00002234 return NULL;
paul718e3742002-12-13 20:15:29 +00002235}
2236
Paul Jakmaf63f06d2011-04-08 12:44:43 +01002237static int
paul718e3742002-12-13 20:15:29 +00002238ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2239{
2240 /* Check match the Area ID of the receiving interface. */
2241 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2242 return 1;
2243
2244 return 0;
2245}
2246
2247/* Unbound socket will accept any Raw IP packets if proto is matched.
2248 To prevent it, compare src IP address and i/f address with masking
2249 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002250static int
paul718e3742002-12-13 20:15:29 +00002251ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2252{
2253 struct in_addr mask, me, him;
2254
2255 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2256 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2257 return 1;
2258
2259 masklen2ip (oi->address->prefixlen, &mask);
2260
2261 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2262 him.s_addr = ip_src.s_addr & mask.s_addr;
2263
2264 if (IPV4_ADDR_SAME (&me, &him))
2265 return 1;
2266
2267 return 0;
2268}
2269
paul4dadc292005-05-06 21:37:42 +00002270static int
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002271ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +00002272{
2273 int ret = 0;
2274 struct crypt_key *ck;
2275
2276 switch (ntohs (ospfh->auth_type))
2277 {
2278 case OSPF_AUTH_NULL:
2279 ret = 1;
2280 break;
2281 case OSPF_AUTH_SIMPLE:
2282 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2283 ret = 1;
2284 else
2285 ret = 0;
2286 break;
2287 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002288 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002289 {
2290 ret = 0;
2291 break;
2292 }
2293
2294 /* This is very basic, the digest processing is elsewhere */
2295 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2296 ospfh->u.crypt.key_id == ck->key_id &&
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002297 ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE <= OSPF_MAX_PACKET_SIZE)
paul718e3742002-12-13 20:15:29 +00002298 ret = 1;
2299 else
2300 ret = 0;
2301 break;
2302 default:
2303 ret = 0;
2304 break;
2305 }
2306
2307 return ret;
2308}
2309
paul4dadc292005-05-06 21:37:42 +00002310static int
paul718e3742002-12-13 20:15:29 +00002311ospf_check_sum (struct ospf_header *ospfh)
2312{
2313 u_int32_t ret;
2314 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002315
2316 /* clear auth_data for checksum. */
2317 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2318
2319 /* keep checksum and clear. */
2320 sum = ospfh->checksum;
2321 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2322
2323 /* calculate checksum. */
2324 ret = in_cksum (ospfh, ntohs (ospfh->length));
2325
2326 if (ret != sum)
2327 {
2328 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2329 ret, sum);
2330 return 0;
2331 }
2332
2333 return 1;
2334}
2335
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002336/* Verify, that given link/TOS records are properly sized/aligned and match
2337 Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2338static unsigned
2339ospf_router_lsa_links_examin
2340(
2341 struct router_lsa_link * link,
2342 u_int16_t linkbytes,
2343 const u_int16_t num_links
2344)
2345{
2346 unsigned counted_links = 0, thislinklen;
2347
2348 while (linkbytes)
2349 {
2350 thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
2351 if (thislinklen > linkbytes)
2352 {
2353 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2354 zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
2355 return MSG_NG;
2356 }
2357 link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
2358 linkbytes -= thislinklen;
2359 counted_links++;
2360 }
2361 if (counted_links != num_links)
2362 {
2363 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2364 zlog_debug ("%s: %u link blocks declared, %u present",
2365 __func__, num_links, counted_links);
2366 return MSG_NG;
2367 }
2368 return MSG_OK;
2369}
2370
2371/* Verify, that the given LSA is properly sized/aligned (including type-specific
2372 minimum length constraint). */
2373static unsigned
2374ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
2375{
2376 unsigned ret;
2377 struct router_lsa * rlsa;
2378 if
2379 (
2380 lsah->type < OSPF_MAX_LSA &&
2381 ospf_lsa_minlen[lsah->type] &&
2382 lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
2383 )
2384 {
2385 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2386 zlog_debug ("%s: undersized (%u B) %s",
2387 __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
2388 return MSG_NG;
2389 }
2390 switch (lsah->type)
2391 {
2392 case OSPF_ROUTER_LSA:
2393 /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
2394 if (headeronly)
2395 {
2396 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2397 break;
2398 }
2399 rlsa = (struct router_lsa *) lsah;
2400 ret = ospf_router_lsa_links_examin
2401 (
2402 (struct router_lsa_link *) rlsa->link,
2403 lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
2404 ntohs (rlsa->links) /* 16 bits */
2405 );
2406 break;
2407 case OSPF_AS_EXTERNAL_LSA:
2408 /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
2409 case OSPF_AS_NSSA_LSA:
2410 /* RFC3101 C, idem */
2411 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
2412 break;
2413 /* Following LSA types are considered OK length-wise as soon as their minimum
2414 * length constraint is met and length of the whole LSA is a multiple of 4
2415 * (basic LSA header size is already a multiple of 4). */
2416 case OSPF_NETWORK_LSA:
2417 /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2418 case OSPF_SUMMARY_LSA:
2419 case OSPF_ASBR_SUMMARY_LSA:
2420 /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
2421#ifdef HAVE_OPAQUE_LSA
2422 case OSPF_OPAQUE_LINK_LSA:
2423 case OSPF_OPAQUE_AREA_LSA:
2424 case OSPF_OPAQUE_AS_LSA:
2425 /* RFC5250 A.2, "some number of octets (of application-specific
2426 * data) padded to 32-bit alignment." This is considered equivalent
2427 * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
2428 * file for the detailed analysis of this passage. */
2429#endif
2430 ret = lsalen % 4 ? MSG_NG : MSG_OK;
2431 break;
2432 default:
2433 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2434 zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
2435 return MSG_NG;
2436 }
2437 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2438 zlog_debug ("%s: alignment error in %s",
2439 __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
2440 return ret;
2441}
2442
2443/* Verify if the provided input buffer is a valid sequence of LSAs. This
2444 includes verification of LSA blocks length/alignment and dispatching
2445 of deeper-level checks. */
2446static unsigned
2447ospf_lsaseq_examin
2448(
2449 struct lsa_header *lsah, /* start of buffered data */
2450 size_t length,
2451 const u_char headeronly,
2452 /* When declared_num_lsas is not 0, compare it to the real number of LSAs
2453 and treat the difference as an error. */
2454 const u_int32_t declared_num_lsas
2455)
2456{
2457 u_int32_t counted_lsas = 0;
2458
2459 while (length)
2460 {
2461 u_int16_t lsalen;
2462 if (length < OSPF_LSA_HEADER_SIZE)
2463 {
2464 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2465 zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
2466 __func__, length, counted_lsas);
2467 return MSG_NG;
2468 }
2469 /* save on ntohs() calls here and in the LSA validator */
2470 lsalen = ntohs (lsah->length);
2471 if (lsalen < OSPF_LSA_HEADER_SIZE)
2472 {
2473 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2474 zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
2475 __func__, counted_lsas, lsalen);
2476 return MSG_NG;
2477 }
2478 if (headeronly)
2479 {
2480 /* less checks here and in ospf_lsa_examin() */
2481 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
2482 {
2483 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2484 zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
2485 return MSG_NG;
2486 }
2487 lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
2488 length -= OSPF_LSA_HEADER_SIZE;
2489 }
2490 else
2491 {
2492 /* make sure the input buffer is deep enough before further checks */
2493 if (lsalen > length)
2494 {
2495 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2496 zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2497 __func__, counted_lsas, lsalen, length);
2498 return MSG_NG;
2499 }
2500 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
2501 {
2502 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2503 zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
2504 return MSG_NG;
2505 }
2506 lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
2507 length -= lsalen;
2508 }
2509 counted_lsas++;
2510 }
2511
2512 if (declared_num_lsas && counted_lsas != declared_num_lsas)
2513 {
2514 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2515 zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
2516 __func__, declared_num_lsas, counted_lsas);
2517 return MSG_NG;
2518 }
2519 return MSG_OK;
2520}
2521
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002522/* Verify a complete OSPF packet for proper sizing/alignment. */
2523static unsigned
2524ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2525{
2526 u_int16_t bytesdeclared;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002527 unsigned ret;
2528 struct ospf_ls_update * lsupd;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002529
2530 /* Length, 1st approximation. */
2531 if (bytesonwire < OSPF_HEADER_SIZE)
2532 {
2533 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2534 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2535 return MSG_NG;
2536 }
2537 /* Now it is safe to access header fields. Performing length check, allow
2538 * for possible extra bytes of crypto auth/padding, which are not counted
2539 * in the OSPF header "length" field. */
2540 bytesdeclared = ntohs (oh->length);
2541 if (bytesdeclared > bytesonwire)
2542 {
2543 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2544 zlog_debug ("%s: packet length error (%u real, %u declared)",
2545 __func__, bytesonwire, bytesdeclared);
2546 return MSG_NG;
2547 }
2548 /* Length, 2nd approximation. The type-specific constraint is checked
2549 against declared length, not amount of bytes on wire. */
2550 if
2551 (
2552 oh->type >= OSPF_MSG_HELLO &&
2553 oh->type <= OSPF_MSG_LS_ACK &&
2554 bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2555 )
2556 {
2557 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2558 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2559 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2560 return MSG_NG;
2561 }
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002562 switch (oh->type)
2563 {
2564 case OSPF_MSG_HELLO:
2565 /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
2566 by N>=0 router-IDs. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002567 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002568 break;
2569 case OSPF_MSG_DB_DESC:
2570 /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
2571 by N>=0 header-only LSAs. */
2572 ret = ospf_lsaseq_examin
2573 (
2574 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002575 bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002576 1, /* header-only LSAs */
2577 0
2578 );
2579 break;
2580 case OSPF_MSG_LS_REQ:
2581 /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002582 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002583 OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
2584 break;
2585 case OSPF_MSG_LS_UPD:
2586 /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
2587 by N>=0 full LSAs (with N declared beforehand). */
2588 lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
2589 ret = ospf_lsaseq_examin
2590 (
2591 (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002592 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002593 0, /* full LSAs */
2594 ntohl (lsupd->num_lsas) /* 32 bits */
2595 );
2596 break;
2597 case OSPF_MSG_LS_ACK:
2598 /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
2599 ret = ospf_lsaseq_examin
2600 (
2601 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
Denis Ovsienkob29adf92012-02-20 23:08:10 +04002602 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
Denis Ovsienko4e31de72012-02-17 16:20:50 +04002603 1, /* header-only LSAs */
2604 0
2605 );
2606 break;
2607 default:
2608 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2609 zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
2610 return MSG_NG;
2611 }
2612 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2613 zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
2614 return ret;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002615}
2616
paul718e3742002-12-13 20:15:29 +00002617/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002618static int
paul718e3742002-12-13 20:15:29 +00002619ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2620 struct ip *iph, struct ospf_header *ospfh)
2621{
2622 /* check version. */
2623 if (ospfh->version != OSPF_VERSION)
2624 {
2625 zlog_warn ("interface %s: ospf_read version number mismatch.",
2626 IF_NAME (oi));
2627 return -1;
2628 }
2629
Denis Ovsienko71775042011-09-26 13:18:02 +04002630 /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
2631 if (ospfh->type < 1 || ospfh->type > 5)
2632 {
2633 zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
2634 return -1;
2635 }
2636
paul718e3742002-12-13 20:15:29 +00002637 /* Check Area ID. */
2638 if (!ospf_check_area_id (oi, ospfh))
2639 {
2640 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2641 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2642 return -1;
2643 }
2644
2645 /* Check network mask, Silently discarded. */
2646 if (! ospf_check_network_mask (oi, iph->ip_src))
2647 {
2648 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2649 IF_NAME (oi), inet_ntoa (iph->ip_src));
2650 return -1;
2651 }
2652
2653 /* Check authentication. */
2654 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2655 {
paulc6371712006-01-17 17:49:53 +00002656 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2657 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002658 return -1;
2659 }
2660
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002661 if (! ospf_check_auth (oi, ospfh))
paul718e3742002-12-13 20:15:29 +00002662 {
2663 zlog_warn ("interface %s: ospf_read authentication failed.",
2664 IF_NAME (oi));
2665 return -1;
2666 }
2667
2668 /* if check sum is invalid, packet is discarded. */
2669 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2670 {
2671 if (! ospf_check_sum (ospfh))
2672 {
2673 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2674 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2675 return -1;
2676 }
2677 }
2678 else
2679 {
2680 if (ospfh->checksum != 0)
2681 return -1;
Denis Ovsienko2d8223c2012-01-30 20:32:39 +04002682 if (ospf_check_md5_digest (oi, ospfh) == 0)
paul718e3742002-12-13 20:15:29 +00002683 {
2684 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2685 IF_NAME (oi));
2686 return -1;
2687 }
2688 }
2689
2690 return 0;
2691}
2692
2693/* Starting point of packet process function. */
2694int
2695ospf_read (struct thread *thread)
2696{
2697 int ret;
2698 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002699 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002700 struct ospf_interface *oi;
2701 struct ip *iph;
2702 struct ospf_header *ospfh;
2703 u_int16_t length;
2704 struct interface *ifp;
2705
2706 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002707 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002708
2709 /* prepare for next packet. */
2710 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002711
ajs5c333492005-02-23 15:43:01 +00002712 stream_reset(ospf->ibuf);
2713 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002714 return -1;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002715 /* This raw packet is known to be at least as big as its IP header. */
paul718e3742002-12-13 20:15:29 +00002716
ajs5c333492005-02-23 15:43:01 +00002717 /* Note that there should not be alignment problems with this assignment
2718 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002719 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002720 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002721
paulac191232004-10-22 12:05:17 +00002722 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002723 /* Handle cases where the platform does not support retrieving the ifindex,
2724 and also platforms (such as Solaris 8) that claim to support ifindex
2725 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002726 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002727
pauld3f0d622004-05-05 15:27:15 +00002728 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002729 return 0;
paul718e3742002-12-13 20:15:29 +00002730
2731 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002732 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002733 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002734
paul718e3742002-12-13 20:15:29 +00002735 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002736 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002737 {
pauld3241812003-09-29 12:42:39 +00002738 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2739 {
ajs2a42e282004-12-08 18:43:03 +00002740 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002741 inet_ntoa (iph->ip_src));
2742 }
paul718e3742002-12-13 20:15:29 +00002743 return 0;
2744 }
2745
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002746 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2747 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002748 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002749
paul718e3742002-12-13 20:15:29 +00002750 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002751 if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
2752 return -1;
2753 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002754
2755 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002756 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002757
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002758 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2759 after the passive/backbone/other checks below are passed. These checks
2760 in turn access the fields of unverified "ospfh" structure for their own
2761 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002762
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002763 /* If incoming interface is passive one, ignore it. */
2764 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2765 {
2766 char buf[3][INET_ADDRSTRLEN];
2767
2768 if (IS_DEBUG_OSPF_EVENT)
2769 zlog_debug ("ignoring packet from router %s sent to %s, "
2770 "received on a passive interface, %s",
2771 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2772 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2773 inet_ntop(AF_INET, &oi->address->u.prefix4,
2774 buf[2], sizeof(buf[2])));
2775
2776 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2777 {
2778 /* Try to fix multicast membership.
2779 * Some OS:es may have problems in this area,
2780 * make sure it is removed.
2781 */
2782 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2783 ospf_if_set_multicast(oi);
2784 }
2785 return 0;
2786 }
2787
2788
pauld3f0d622004-05-05 15:27:15 +00002789 /* if no local ospf_interface,
2790 * or header area is backbone but ospf_interface is not
2791 * check for VLINK interface
2792 */
2793 if ( (oi == NULL) ||
2794 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2795 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2796 )
2797 {
2798 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2799 {
Paul Jakma88871b12006-06-15 11:41:19 +00002800 if (IS_DEBUG_OSPF_EVENT)
2801 zlog_debug ("Packet from [%s] received on link %s"
2802 " but no ospf_interface",
2803 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002804 return 0;
2805 }
2806 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002807
pauld3f0d622004-05-05 15:27:15 +00002808 /* else it must be a local ospf interface, check it was received on
2809 * correct link
2810 */
2811 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002812 {
Paul Jakma11637432009-08-11 12:25:42 +01002813 if (IS_DEBUG_OSPF_EVENT)
2814 zlog_warn ("Packet from [%s] received on wrong link %s",
2815 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002816 return 0;
2817 }
ajs847947f2005-02-02 18:38:48 +00002818 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002819 {
ajsba6454e2005-02-08 15:37:30 +00002820 char buf[2][INET_ADDRSTRLEN];
2821 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002822 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002823 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2824 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2825 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002826 /* Fix multicast memberships? */
2827 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002828 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002829 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002830 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002831 if (oi->multicast_memberships)
2832 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002833 return 0;
2834 }
paul718e3742002-12-13 20:15:29 +00002835
2836 /*
2837 * If the received packet is destined for AllDRouters, the packet
2838 * should be accepted only if the received ospf interface state is
2839 * either DR or Backup -- endo.
2840 */
2841 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2842 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2843 {
ajsba6454e2005-02-08 15:37:30 +00002844 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002845 inet_ntoa (iph->ip_src), IF_NAME (oi),
2846 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002847 /* Try to fix multicast membership. */
2848 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2849 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002850 return 0;
2851 }
2852
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002853 /* Verify more OSPF header fields. */
2854 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2855 if (ret < 0)
2856 {
2857 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2858 zlog_debug ("ospf_read[%s]: Header check failed, "
2859 "dropping.",
2860 inet_ntoa (iph->ip_src));
2861 return ret;
2862 }
2863
paul718e3742002-12-13 20:15:29 +00002864 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002865 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2866 {
paul718e3742002-12-13 20:15:29 +00002867 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002868 {
ajs2a42e282004-12-08 18:43:03 +00002869 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002870 ospf_packet_dump (ibuf);
2871 }
paul718e3742002-12-13 20:15:29 +00002872
ajs2a42e282004-12-08 18:43:03 +00002873 zlog_debug ("%s received from [%s] via [%s]",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +04002874 LOOKUP (ospf_packet_type_str, ospfh->type),
paul1aa7b392003-04-08 08:51:58 +00002875 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002876 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2877 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002878
2879 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002880 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002881 }
paul718e3742002-12-13 20:15:29 +00002882
paul9985f832005-02-09 15:51:56 +00002883 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002884
2885 /* Adjust size to message length. */
2886 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2887
2888 /* Read rest of the packet and call each sort of packet routine. */
2889 switch (ospfh->type)
2890 {
2891 case OSPF_MSG_HELLO:
2892 ospf_hello (iph, ospfh, ibuf, oi, length);
2893 break;
2894 case OSPF_MSG_DB_DESC:
2895 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2896 break;
2897 case OSPF_MSG_LS_REQ:
2898 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2899 break;
2900 case OSPF_MSG_LS_UPD:
2901 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2902 break;
2903 case OSPF_MSG_LS_ACK:
2904 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2905 break;
2906 default:
2907 zlog (NULL, LOG_WARNING,
2908 "interface %s: OSPF packet header type %d is illegal",
2909 IF_NAME (oi), ospfh->type);
2910 break;
2911 }
2912
paul718e3742002-12-13 20:15:29 +00002913 return 0;
2914}
2915
2916/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002917static void
paul718e3742002-12-13 20:15:29 +00002918ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2919{
2920 struct ospf_header *ospfh;
2921
2922 ospfh = (struct ospf_header *) STREAM_DATA (s);
2923
2924 ospfh->version = (u_char) OSPF_VERSION;
2925 ospfh->type = (u_char) type;
2926
paul68980082003-03-25 05:07:42 +00002927 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002928
2929 ospfh->checksum = 0;
2930 ospfh->area_id = oi->area->area_id;
2931 ospfh->auth_type = htons (ospf_auth_type (oi));
2932
2933 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2934
paul9985f832005-02-09 15:51:56 +00002935 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002936}
2937
2938/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002939static int
paul718e3742002-12-13 20:15:29 +00002940ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2941{
2942 struct crypt_key *ck;
2943
2944 switch (ospf_auth_type (oi))
2945 {
2946 case OSPF_AUTH_NULL:
2947 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2948 break;
2949 case OSPF_AUTH_SIMPLE:
2950 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2951 OSPF_AUTH_SIMPLE_SIZE);
2952 break;
2953 case OSPF_AUTH_CRYPTOGRAPHIC:
2954 /* If key is not set, then set 0. */
2955 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2956 {
2957 ospfh->u.crypt.zero = 0;
2958 ospfh->u.crypt.key_id = 0;
2959 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2960 }
2961 else
2962 {
paul1eb8ef22005-04-07 07:30:20 +00002963 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002964 ospfh->u.crypt.zero = 0;
2965 ospfh->u.crypt.key_id = ck->key_id;
2966 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2967 }
2968 /* note: the seq is done in ospf_make_md5_digest() */
2969 break;
2970 default:
2971 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2972 break;
2973 }
2974
2975 return 0;
2976}
2977
2978/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002979static void
paul718e3742002-12-13 20:15:29 +00002980ospf_fill_header (struct ospf_interface *oi,
2981 struct stream *s, u_int16_t length)
2982{
2983 struct ospf_header *ospfh;
2984
2985 ospfh = (struct ospf_header *) STREAM_DATA (s);
2986
2987 /* Fill length. */
2988 ospfh->length = htons (length);
2989
2990 /* Calculate checksum. */
2991 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2992 ospfh->checksum = in_cksum (ospfh, length);
2993 else
2994 ospfh->checksum = 0;
2995
2996 /* Add Authentication Data. */
2997 ospf_make_auth (oi, ospfh);
2998}
2999
paul4dadc292005-05-06 21:37:42 +00003000static int
paul718e3742002-12-13 20:15:29 +00003001ospf_make_hello (struct ospf_interface *oi, struct stream *s)
3002{
3003 struct ospf_neighbor *nbr;
3004 struct route_node *rn;
3005 u_int16_t length = OSPF_HELLO_MIN_SIZE;
3006 struct in_addr mask;
3007 unsigned long p;
3008 int flag = 0;
3009
3010 /* Set netmask of interface. */
3011 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
3012 oi->type != OSPF_IFTYPE_VIRTUALLINK)
3013 masklen2ip (oi->address->prefixlen, &mask);
3014 else
3015 memset ((char *) &mask, 0, sizeof (struct in_addr));
3016 stream_put_ipv4 (s, mask.s_addr);
3017
3018 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00003019 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
3020 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
3021 else
3022 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00003023
3024 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003025 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00003026 OPTIONS(oi), IF_NAME (oi));
3027
3028 /* Set Options. */
3029 stream_putc (s, OPTIONS (oi));
3030
3031 /* Set Router Priority. */
3032 stream_putc (s, PRIORITY (oi));
3033
3034 /* Set Router Dead Interval. */
3035 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
3036
3037 /* Set Designated Router. */
3038 stream_put_ipv4 (s, DR (oi).s_addr);
3039
paul9985f832005-02-09 15:51:56 +00003040 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003041
3042 /* Set Backup Designated Router. */
3043 stream_put_ipv4 (s, BDR (oi).s_addr);
3044
3045 /* Add neighbor seen. */
3046 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00003047 if ((nbr = rn->info))
3048 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
3049 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
3050 if (nbr->state != NSM_Down) /* This is myself for DR election. */
3051 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003052 {
3053 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00003054 if (nbr->d_router.s_addr != 0
3055 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
3056 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
3057 flag = 1;
paul718e3742002-12-13 20:15:29 +00003058
3059 stream_put_ipv4 (s, nbr->router_id.s_addr);
3060 length += 4;
3061 }
3062
3063 /* Let neighbor generate BackupSeen. */
3064 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00003065 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00003066
3067 return length;
3068}
3069
paul4dadc292005-05-06 21:37:42 +00003070static int
paul718e3742002-12-13 20:15:29 +00003071ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
3072 struct stream *s)
3073{
3074 struct ospf_lsa *lsa;
3075 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
3076 u_char options;
3077 unsigned long pp;
3078 int i;
3079 struct ospf_lsdb *lsdb;
3080
3081 /* Set Interface MTU. */
3082 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3083 stream_putw (s, 0);
3084 else
3085 stream_putw (s, oi->ifp->mtu);
3086
3087 /* Set Options. */
3088 options = OPTIONS (oi);
3089#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003090 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00003091 {
3092 if (IS_SET_DD_I (nbr->dd_flags)
3093 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
3094 /*
3095 * Set O-bit in the outgoing DD packet for capablity negotiation,
3096 * if one of following case is applicable.
3097 *
3098 * 1) WaitTimer expiration event triggered the neighbor state to
3099 * change to Exstart, but no (valid) DD packet has received
3100 * from the neighbor yet.
3101 *
3102 * 2) At least one DD packet with O-bit on has received from the
3103 * neighbor.
3104 */
3105 SET_FLAG (options, OSPF_OPTION_O);
3106 }
3107#endif /* HAVE_OPAQUE_LSA */
3108 stream_putc (s, options);
3109
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003110 /* DD flags */
paul9985f832005-02-09 15:51:56 +00003111 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003112 stream_putc (s, nbr->dd_flags);
3113
3114 /* Set DD Sequence Number. */
3115 stream_putl (s, nbr->dd_seqnum);
3116
Paul Jakmab5aeb442006-08-30 18:47:37 +00003117 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00003118 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00003119 goto empty;
paul718e3742002-12-13 20:15:29 +00003120
3121 /* Describe LSA Header from Database Summary List. */
3122 lsdb = &nbr->db_sum;
3123
3124 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3125 {
3126 struct route_table *table = lsdb->type[i].db;
3127 struct route_node *rn;
3128
3129 for (rn = route_top (table); rn; rn = route_next (rn))
3130 if ((lsa = rn->info) != NULL)
3131 {
3132#ifdef HAVE_OPAQUE_LSA
3133 if (IS_OPAQUE_LSA (lsa->data->type)
3134 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
3135 {
3136 /* Suppress advertising opaque-informations. */
3137 /* Remove LSA from DB summary list. */
3138 ospf_lsdb_delete (lsdb, lsa);
3139 continue;
3140 }
3141#endif /* HAVE_OPAQUE_LSA */
3142
3143 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
3144 {
3145 struct lsa_header *lsah;
3146 u_int16_t ls_age;
3147
3148 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003149 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003150 break;
3151
3152 /* Keep pointer to LS age. */
3153 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00003154 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003155
3156 /* Proceed stream pointer. */
3157 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3158 length += OSPF_LSA_HEADER_SIZE;
3159
3160 /* Set LS age. */
3161 ls_age = LS_AGE (lsa);
3162 lsah->ls_age = htons (ls_age);
3163
3164 }
3165
3166 /* Remove LSA from DB summary list. */
3167 ospf_lsdb_delete (lsdb, lsa);
3168 }
3169 }
3170
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003171 /* Update 'More' bit */
3172 if (ospf_db_summary_isempty (nbr))
3173 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00003174empty:
3175 if (nbr->state >= NSM_Exchange)
3176 {
3177 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
3178 /* Rewrite DD flags */
3179 stream_putc_at (s, pp, nbr->dd_flags);
3180 }
3181 else
3182 {
3183 assert (IS_SET_DD_M(nbr->dd_flags));
3184 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00003185 }
paul718e3742002-12-13 20:15:29 +00003186 return length;
3187}
3188
paul4dadc292005-05-06 21:37:42 +00003189static int
paul718e3742002-12-13 20:15:29 +00003190ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
3191 unsigned long delta, struct ospf_neighbor *nbr,
3192 struct ospf_lsa *lsa)
3193{
3194 struct ospf_interface *oi;
3195
3196 oi = nbr->oi;
3197
3198 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00003199 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00003200 return 0;
3201
3202 stream_putl (s, lsa->data->type);
3203 stream_put_ipv4 (s, lsa->data->id.s_addr);
3204 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
3205
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003206 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00003207 nbr->ls_req_last = ospf_lsa_lock (lsa);
3208
3209 *length += 12;
3210 return 1;
3211}
3212
paul4dadc292005-05-06 21:37:42 +00003213static int
paul718e3742002-12-13 20:15:29 +00003214ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
3215{
3216 struct ospf_lsa *lsa;
3217 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003218 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00003219 struct route_table *table;
3220 struct route_node *rn;
3221 int i;
3222 struct ospf_lsdb *lsdb;
3223
3224 lsdb = &nbr->ls_req;
3225
3226 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3227 {
3228 table = lsdb->type[i].db;
3229 for (rn = route_top (table); rn; rn = route_next (rn))
3230 if ((lsa = (rn->info)) != NULL)
3231 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
3232 {
3233 route_unlock_node (rn);
3234 break;
3235 }
3236 }
3237 return length;
3238}
3239
paul4dadc292005-05-06 21:37:42 +00003240static int
paul718e3742002-12-13 20:15:29 +00003241ls_age_increment (struct ospf_lsa *lsa, int delay)
3242{
3243 int age;
3244
3245 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
3246
3247 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3248}
3249
paul4dadc292005-05-06 21:37:42 +00003250static int
hasso52dc7ee2004-09-23 19:18:23 +00003251ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003252{
3253 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00003254 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003255 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00003256 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00003257 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003258 unsigned long pp;
3259 int count = 0;
3260
3261 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003262 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00003263
paul9985f832005-02-09 15:51:56 +00003264 pp = stream_get_endp (s);
3265 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003266 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00003267
gdt86f1fd92005-01-10 14:20:43 +00003268 /* Calculate amount of packet usable for data. */
3269 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3270
paul718e3742002-12-13 20:15:29 +00003271 while ((node = listhead (update)) != NULL)
3272 {
3273 struct lsa_header *lsah;
3274 u_int16_t ls_age;
3275
3276 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003277 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00003278
paul1eb8ef22005-04-07 07:30:20 +00003279 lsa = listgetdata (node);
3280
paul718e3742002-12-13 20:15:29 +00003281 assert (lsa->data);
3282
paul68b73392004-09-12 14:21:37 +00003283 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00003284 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00003285 break;
3286
paul718e3742002-12-13 20:15:29 +00003287 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00003288 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003289
3290 /* Put LSA to Link State Request. */
3291 stream_put (s, lsa->data, ntohs (lsa->data->length));
3292
3293 /* Set LS age. */
3294 /* each hop must increment an lsa_age by transmit_delay
3295 of OSPF interface */
3296 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3297 lsah->ls_age = htons (ls_age);
3298
3299 length += ntohs (lsa->data->length);
3300 count++;
3301
3302 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003303 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003304 }
3305
3306 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003307 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003308
3309 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003310 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003311 return length;
3312}
3313
paul4dadc292005-05-06 21:37:42 +00003314static int
hasso52dc7ee2004-09-23 19:18:23 +00003315ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003316{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003317 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003318 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003319 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003320 struct ospf_lsa *lsa;
3321
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003322 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003323 {
paul718e3742002-12-13 20:15:29 +00003324 assert (lsa);
3325
gdt86f1fd92005-01-10 14:20:43 +00003326 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003327 break;
3328
3329 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3330 length += OSPF_LSA_HEADER_SIZE;
3331
paul718e3742002-12-13 20:15:29 +00003332 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003333 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003334 }
3335
paul718e3742002-12-13 20:15:29 +00003336 return length;
3337}
3338
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003339static void
3340ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003341{
3342 struct ospf_packet *op;
3343 u_int16_t length = OSPF_HEADER_SIZE;
3344
3345 op = ospf_packet_new (oi->ifp->mtu);
3346
3347 /* Prepare OSPF common header. */
3348 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3349
3350 /* Prepare OSPF Hello body. */
3351 length += ospf_make_hello (oi, op->s);
3352
3353 /* Fill OSPF header. */
3354 ospf_fill_header (oi, op->s, length);
3355
3356 /* Set packet length. */
3357 op->length = length;
3358
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003359 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003360
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003361 /* Add packet to the top of the interface output queue, so that they
3362 * can't get delayed by things like long queues of LS Update packets
3363 */
3364 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003365
3366 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003367 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003368}
3369
paul4dadc292005-05-06 21:37:42 +00003370static void
paul718e3742002-12-13 20:15:29 +00003371ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3372{
3373 struct ospf_interface *oi;
3374
3375 oi = nbr_nbma->oi;
3376 assert(oi);
3377
3378 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003379 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003380 return;
3381
3382 if (oi->type != OSPF_IFTYPE_NBMA)
3383 return;
3384
3385 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3386 return;
3387
3388 if (PRIORITY(oi) == 0)
3389 return;
3390
3391 if (nbr_nbma->priority == 0
3392 && oi->state != ISM_DR && oi->state != ISM_Backup)
3393 return;
3394
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003395 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003396}
3397
3398int
3399ospf_poll_timer (struct thread *thread)
3400{
3401 struct ospf_nbr_nbma *nbr_nbma;
3402
3403 nbr_nbma = THREAD_ARG (thread);
3404 nbr_nbma->t_poll = NULL;
3405
3406 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003407 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003408 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3409
3410 ospf_poll_send (nbr_nbma);
3411
3412 if (nbr_nbma->v_poll > 0)
3413 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3414 nbr_nbma->v_poll);
3415
3416 return 0;
3417}
3418
3419
3420int
3421ospf_hello_reply_timer (struct thread *thread)
3422{
3423 struct ospf_neighbor *nbr;
3424
3425 nbr = THREAD_ARG (thread);
3426 nbr->t_hello_reply = NULL;
3427
3428 assert (nbr->oi);
3429
3430 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003431 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003432 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3433
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003434 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003435
3436 return 0;
3437}
3438
3439/* Send OSPF Hello. */
3440void
3441ospf_hello_send (struct ospf_interface *oi)
3442{
paul718e3742002-12-13 20:15:29 +00003443 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003444 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003445 return;
3446
paul718e3742002-12-13 20:15:29 +00003447 if (oi->type == OSPF_IFTYPE_NBMA)
3448 {
3449 struct ospf_neighbor *nbr;
3450 struct route_node *rn;
3451
3452 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3453 if ((nbr = rn->info))
3454 if (nbr != oi->nbr_self)
3455 if (nbr->state != NSM_Down)
3456 {
3457 /* RFC 2328 Section 9.5.1
3458 If the router is not eligible to become Designated Router,
3459 it must periodically send Hello Packets to both the
3460 Designated Router and the Backup Designated Router (if they
3461 exist). */
3462 if (PRIORITY(oi) == 0 &&
3463 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3464 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3465 continue;
3466
3467 /* If the router is eligible to become Designated Router, it
3468 must periodically send Hello Packets to all neighbors that
3469 are also eligible. In addition, if the router is itself the
3470 Designated Router or Backup Designated Router, it must also
3471 send periodic Hello Packets to all other neighbors. */
3472
3473 if (nbr->priority == 0 && oi->state == ISM_DROther)
3474 continue;
3475 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003476 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003477 }
paul718e3742002-12-13 20:15:29 +00003478 }
3479 else
3480 {
3481 /* Decide destination address. */
3482 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003483 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3484 else
3485 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003486 }
3487}
3488
3489/* Send OSPF Database Description. */
3490void
3491ospf_db_desc_send (struct ospf_neighbor *nbr)
3492{
3493 struct ospf_interface *oi;
3494 struct ospf_packet *op;
3495 u_int16_t length = OSPF_HEADER_SIZE;
3496
3497 oi = nbr->oi;
3498 op = ospf_packet_new (oi->ifp->mtu);
3499
3500 /* Prepare OSPF common header. */
3501 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3502
3503 /* Prepare OSPF Database Description body. */
3504 length += ospf_make_db_desc (oi, nbr, op->s);
3505
3506 /* Fill OSPF header. */
3507 ospf_fill_header (oi, op->s, length);
3508
3509 /* Set packet length. */
3510 op->length = length;
3511
3512 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003513 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3514 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3515 else
3516 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003517
3518 /* Add packet to the interface output queue. */
3519 ospf_packet_add (oi, op);
3520
3521 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003522 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003523
3524 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3525 if (nbr->last_send)
3526 ospf_packet_free (nbr->last_send);
3527 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003528 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003529}
3530
3531/* Re-send Database Description. */
3532void
3533ospf_db_desc_resend (struct ospf_neighbor *nbr)
3534{
3535 struct ospf_interface *oi;
3536
3537 oi = nbr->oi;
3538
3539 /* Add packet to the interface output queue. */
3540 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3541
3542 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003543 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003544}
3545
3546/* Send Link State Request. */
3547void
3548ospf_ls_req_send (struct ospf_neighbor *nbr)
3549{
3550 struct ospf_interface *oi;
3551 struct ospf_packet *op;
3552 u_int16_t length = OSPF_HEADER_SIZE;
3553
3554 oi = nbr->oi;
3555 op = ospf_packet_new (oi->ifp->mtu);
3556
3557 /* Prepare OSPF common header. */
3558 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3559
3560 /* Prepare OSPF Link State Request body. */
3561 length += ospf_make_ls_req (nbr, op->s);
3562 if (length == OSPF_HEADER_SIZE)
3563 {
3564 ospf_packet_free (op);
3565 return;
3566 }
3567
3568 /* Fill OSPF header. */
3569 ospf_fill_header (oi, op->s, length);
3570
3571 /* Set packet length. */
3572 op->length = length;
3573
3574 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003575 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3576 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3577 else
3578 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003579
3580 /* Add packet to the interface output queue. */
3581 ospf_packet_add (oi, op);
3582
3583 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003584 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003585
3586 /* Add Link State Request Retransmission Timer. */
3587 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3588}
3589
3590/* Send Link State Update with an LSA. */
3591void
3592ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3593 int flag)
3594{
hasso52dc7ee2004-09-23 19:18:23 +00003595 struct list *update;
paul718e3742002-12-13 20:15:29 +00003596
3597 update = list_new ();
3598
3599 listnode_add (update, lsa);
3600 ospf_ls_upd_send (nbr, update, flag);
3601
3602 list_delete (update);
3603}
3604
paul68b73392004-09-12 14:21:37 +00003605/* Determine size for packet. Must be at least big enough to accomodate next
3606 * LSA on list, which may be bigger than MTU size.
3607 *
3608 * Return pointer to new ospf_packet
3609 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3610 * on packet sizes (in which case offending LSA is deleted from update list)
3611 */
3612static struct ospf_packet *
3613ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3614{
3615 struct ospf_lsa *lsa;
3616 struct listnode *ln;
3617 size_t size;
3618 static char warned = 0;
3619
paul1eb8ef22005-04-07 07:30:20 +00003620 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003621 assert (lsa->data);
3622
3623 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3624 > ospf_packet_max (oi))
3625 {
3626 if (!warned)
3627 {
3628 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3629 "will need to fragment. Not optimal. Try divide up"
3630 " your network with areas. Use 'debug ospf packet send'"
3631 " to see details, or look at 'show ip ospf database ..'");
3632 warned = 1;
3633 }
3634
3635 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003636 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003637 " %d bytes originated by %s, will be fragmented!",
3638 inet_ntoa (lsa->data->id),
3639 ntohs (lsa->data->length),
3640 inet_ntoa (lsa->data->adv_router));
3641
3642 /*
3643 * Allocate just enough to fit this LSA only, to avoid including other
3644 * LSAs in fragmented LSA Updates.
3645 */
3646 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3647 + OSPF_LS_UPD_MIN_SIZE;
3648 }
3649 else
3650 size = oi->ifp->mtu;
3651
3652 if (size > OSPF_MAX_PACKET_SIZE)
3653 {
3654 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003655 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003656 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003657 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003658 (long int) size);
paul68b73392004-09-12 14:21:37 +00003659 list_delete_node (update, ln);
3660 return NULL;
3661 }
3662
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003663 /* IP header is built up separately by ospf_write(). This means, that we must
3664 * reduce the "affordable" size just calculated by length of an IP header.
3665 * This makes sure, that even if we manage to fill the payload with LSA data
3666 * completely, the final packet (our data plus IP header) still fits into
3667 * outgoing interface MTU. This correction isn't really meaningful for an
3668 * oversized LSA, but for consistency the correction is done for both cases.
3669 *
3670 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3671 */
3672 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003673}
3674
paul718e3742002-12-13 20:15:29 +00003675static void
hasso52dc7ee2004-09-23 19:18:23 +00003676ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003677 struct in_addr addr)
3678{
3679 struct ospf_packet *op;
3680 u_int16_t length = OSPF_HEADER_SIZE;
3681
3682 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003683 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003684
3685 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003686
3687 /* Prepare OSPF common header. */
3688 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3689
paul59ea14c2004-07-14 20:50:36 +00003690 /* Prepare OSPF Link State Update body.
3691 * Includes Type-7 translation.
3692 */
paul718e3742002-12-13 20:15:29 +00003693 length += ospf_make_ls_upd (oi, update, op->s);
3694
3695 /* Fill OSPF header. */
3696 ospf_fill_header (oi, op->s, length);
3697
3698 /* Set packet length. */
3699 op->length = length;
3700
3701 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003702 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3703 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3704 else
3705 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003706
3707 /* Add packet to the interface output queue. */
3708 ospf_packet_add (oi, op);
3709
3710 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003711 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003712}
3713
3714static int
3715ospf_ls_upd_send_queue_event (struct thread *thread)
3716{
3717 struct ospf_interface *oi = THREAD_ARG(thread);
3718 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003719 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003720 struct list *update;
paul68b73392004-09-12 14:21:37 +00003721 char again = 0;
paul718e3742002-12-13 20:15:29 +00003722
3723 oi->t_ls_upd_event = NULL;
3724
3725 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003726 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003727
paul736d3442003-07-24 23:22:57 +00003728 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003729 {
paul736d3442003-07-24 23:22:57 +00003730 rnext = route_next (rn);
3731
paul718e3742002-12-13 20:15:29 +00003732 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003733 continue;
paul68b73392004-09-12 14:21:37 +00003734
3735 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003736
paul48fe13b2004-07-27 17:40:44 +00003737 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003738
paul68b73392004-09-12 14:21:37 +00003739 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003740 if (listcount(update) == 0)
3741 {
3742 list_delete (rn->info);
3743 rn->info = NULL;
3744 route_unlock_node (rn);
3745 }
3746 else
paul68b73392004-09-12 14:21:37 +00003747 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003748 }
3749
3750 if (again != 0)
3751 {
3752 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003753 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003754 " %d nodes to try again, raising new event", again);
3755 oi->t_ls_upd_event =
3756 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003757 }
3758
3759 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003760 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003761
paul718e3742002-12-13 20:15:29 +00003762 return 0;
3763}
3764
3765void
hasso52dc7ee2004-09-23 19:18:23 +00003766ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003767{
3768 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003769 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003770 struct prefix_ipv4 p;
3771 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003772 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003773
3774 oi = nbr->oi;
3775
3776 p.family = AF_INET;
3777 p.prefixlen = IPV4_MAX_BITLEN;
3778
3779 /* Decide destination address. */
3780 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3781 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003782 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3783 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003784 else if (flag == OSPF_SEND_PACKET_DIRECT)
3785 p.prefix = nbr->address.u.prefix4;
3786 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3787 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003788 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3789 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003790 else
3791 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3792
3793 if (oi->type == OSPF_IFTYPE_NBMA)
3794 {
3795 if (flag == OSPF_SEND_PACKET_INDIRECT)
3796 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3797 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3798 zlog_warn ("* LS-Update is sent to myself.");
3799 }
3800
3801 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3802
3803 if (rn->info == NULL)
3804 rn->info = list_new ();
3805
paul1eb8ef22005-04-07 07:30:20 +00003806 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003807 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003808
3809 if (oi->t_ls_upd_event == NULL)
3810 oi->t_ls_upd_event =
3811 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3812}
3813
3814static void
hasso52dc7ee2004-09-23 19:18:23 +00003815ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3816 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003817{
3818 struct ospf_packet *op;
3819 u_int16_t length = OSPF_HEADER_SIZE;
3820
3821 op = ospf_packet_new (oi->ifp->mtu);
3822
3823 /* Prepare OSPF common header. */
3824 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3825
3826 /* Prepare OSPF Link State Acknowledgment body. */
3827 length += ospf_make_ls_ack (oi, ack, op->s);
3828
3829 /* Fill OSPF header. */
3830 ospf_fill_header (oi, op->s, length);
3831
3832 /* Set packet length. */
3833 op->length = length;
3834
3835 /* Set destination IP address. */
3836 op->dst = dst;
3837
3838 /* Add packet to the interface output queue. */
3839 ospf_packet_add (oi, op);
3840
3841 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003842 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003843}
3844
3845static int
3846ospf_ls_ack_send_event (struct thread *thread)
3847{
3848 struct ospf_interface *oi = THREAD_ARG (thread);
3849
3850 oi->t_ls_ack_direct = NULL;
3851
3852 while (listcount (oi->ls_ack_direct.ls_ack))
3853 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3854 oi->ls_ack_direct.dst);
3855
3856 return 0;
3857}
3858
3859void
3860ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3861{
3862 struct ospf_interface *oi = nbr->oi;
3863
3864 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3865 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3866
3867 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3868
3869 if (oi->t_ls_ack_direct == NULL)
3870 oi->t_ls_ack_direct =
3871 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3872}
3873
3874/* Send Link State Acknowledgment delayed. */
3875void
3876ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3877{
3878 struct in_addr dst;
3879
3880 /* Decide destination address. */
3881 /* RFC2328 Section 13.5 On non-broadcast
3882 networks, delayed Link State Acknowledgment packets must be
3883 unicast separately over each adjacency (i.e., neighbor whose
3884 state is >= Exchange). */
3885 if (oi->type == OSPF_IFTYPE_NBMA)
3886 {
3887 struct ospf_neighbor *nbr;
3888 struct route_node *rn;
3889
3890 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3891 if ((nbr = rn->info) != NULL)
3892 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3893 while (listcount (oi->ls_ack))
3894 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3895 return;
3896 }
3897 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3898 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3899 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3900 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3901 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3902 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003903 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3904 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003905 else
3906 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3907
3908 while (listcount (oi->ls_ack))
3909 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3910}