blob: b18117b5af47674b9ece2b0160af4dd92fab8765 [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
paul718e3742002-12-13 20:15:29 +000076/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000077static int
paul718e3742002-12-13 20:15:29 +000078ospf_auth_type (struct ospf_interface *oi)
79{
80 int auth_type;
81
82 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
83 auth_type = oi->area->auth_type;
84 else
85 auth_type = OSPF_IF_PARAM (oi, auth_type);
86
87 /* Handle case where MD5 key list is not configured aka Cisco */
88 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
89 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
90 return OSPF_AUTH_NULL;
91
92 return auth_type;
93
94}
95
paul718e3742002-12-13 20:15:29 +000096struct ospf_packet *
97ospf_packet_new (size_t size)
98{
99 struct ospf_packet *new;
100
101 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
102 new->s = stream_new (size);
103
104 return new;
105}
106
107void
108ospf_packet_free (struct ospf_packet *op)
109{
110 if (op->s)
111 stream_free (op->s);
112
113 XFREE (MTYPE_OSPF_PACKET, op);
114
115 op = NULL;
116}
117
118struct ospf_fifo *
119ospf_fifo_new ()
120{
121 struct ospf_fifo *new;
122
123 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
124 return new;
125}
126
127/* Add new packet to fifo. */
128void
129ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
130{
131 if (fifo->tail)
132 fifo->tail->next = op;
133 else
134 fifo->head = op;
135
136 fifo->tail = op;
137
138 fifo->count++;
139}
140
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000141/* Add new packet to head of fifo. */
142static void
143ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
144{
145 op->next = fifo->head;
146
147 if (fifo->tail == NULL)
148 fifo->tail = op;
149
150 fifo->head = op;
151
152 fifo->count++;
153}
154
paul718e3742002-12-13 20:15:29 +0000155/* Delete first packet from fifo. */
156struct ospf_packet *
157ospf_fifo_pop (struct ospf_fifo *fifo)
158{
159 struct ospf_packet *op;
160
161 op = fifo->head;
162
163 if (op)
164 {
165 fifo->head = op->next;
166
167 if (fifo->head == NULL)
168 fifo->tail = NULL;
169
170 fifo->count--;
171 }
172
173 return op;
174}
175
176/* Return first fifo entry. */
177struct ospf_packet *
178ospf_fifo_head (struct ospf_fifo *fifo)
179{
180 return fifo->head;
181}
182
183/* Flush ospf packet fifo. */
184void
185ospf_fifo_flush (struct ospf_fifo *fifo)
186{
187 struct ospf_packet *op;
188 struct ospf_packet *next;
189
190 for (op = fifo->head; op; op = next)
191 {
192 next = op->next;
193 ospf_packet_free (op);
194 }
195 fifo->head = fifo->tail = NULL;
196 fifo->count = 0;
197}
198
199/* Free ospf packet fifo. */
200void
201ospf_fifo_free (struct ospf_fifo *fifo)
202{
203 ospf_fifo_flush (fifo);
204
205 XFREE (MTYPE_OSPF_FIFO, fifo);
206}
207
208void
209ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
210{
ajsc3eab872005-01-29 15:52:07 +0000211 if (!oi->obuf)
212 {
213 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
214 "destination %s) called with NULL obuf, ignoring "
215 "(please report this bug)!\n",
216 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400217 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
ajsc3eab872005-01-29 15:52:07 +0000218 inet_ntoa (op->dst));
219 return;
220 }
221
paul718e3742002-12-13 20:15:29 +0000222 /* Add packet to end of queue. */
223 ospf_fifo_push (oi->obuf, op);
224
225 /* Debug of packet fifo*/
226 /* ospf_fifo_debug (oi->obuf); */
227}
228
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000229static void
230ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
231{
232 if (!oi->obuf)
233 {
234 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
235 "destination %s) called with NULL obuf, ignoring "
236 "(please report this bug)!\n",
237 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko7e0e2cb2012-01-20 22:32:10 +0400238 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000239 inet_ntoa (op->dst));
240 return;
241 }
242
243 /* Add packet to head of queue. */
244 ospf_fifo_push_head (oi->obuf, op);
245
246 /* Debug of packet fifo*/
247 /* ospf_fifo_debug (oi->obuf); */
248}
249
paul718e3742002-12-13 20:15:29 +0000250void
251ospf_packet_delete (struct ospf_interface *oi)
252{
253 struct ospf_packet *op;
254
255 op = ospf_fifo_pop (oi->obuf);
256
257 if (op)
258 ospf_packet_free (op);
259}
260
paul718e3742002-12-13 20:15:29 +0000261struct ospf_packet *
262ospf_packet_dup (struct ospf_packet *op)
263{
264 struct ospf_packet *new;
265
paul37163d62003-02-03 18:40:56 +0000266 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000267 /* XXX size_t */
268 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
269 (u_long)STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000270
271 /* Reserve space for MD5 authentication that may be added later. */
272 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000273 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000274
275 new->dst = op->dst;
276 new->length = op->length;
277
278 return new;
279}
280
gdt86f1fd92005-01-10 14:20:43 +0000281/* XXX inline */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100282static unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000283ospf_packet_authspace (struct ospf_interface *oi)
284{
285 int auth = 0;
286
287 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
288 auth = OSPF_AUTH_MD5_SIZE;
289
290 return auth;
291}
292
paul4dadc292005-05-06 21:37:42 +0000293static unsigned int
paul718e3742002-12-13 20:15:29 +0000294ospf_packet_max (struct ospf_interface *oi)
295{
296 int max;
297
gdt86f1fd92005-01-10 14:20:43 +0000298 max = oi->ifp->mtu - ospf_packet_authspace(oi);
299
paul68b73392004-09-12 14:21:37 +0000300 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000301
302 return max;
303}
304
305
paul4dadc292005-05-06 21:37:42 +0000306static int
paul718e3742002-12-13 20:15:29 +0000307ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
308 u_int16_t length)
309{
paul6c835672004-10-11 11:00:30 +0000310 unsigned char *ibuf;
vincentc1a03d42005-09-28 15:47:44 +0000311 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000312 unsigned char digest[OSPF_AUTH_MD5_SIZE];
313 unsigned char *pdigest;
314 struct crypt_key *ck;
315 struct ospf_header *ospfh;
316 struct ospf_neighbor *nbr;
317
318
319 ibuf = STREAM_PNT (s);
320 ospfh = (struct ospf_header *) ibuf;
321
322 /* Get pointer to the end of the packet. */
323 pdigest = ibuf + length;
324
325 /* Get secret key. */
326 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
327 ospfh->u.crypt.key_id);
328 if (ck == NULL)
329 {
330 zlog_warn ("interface %s: ospf_check_md5 no key %d",
331 IF_NAME (oi), ospfh->u.crypt.key_id);
332 return 0;
333 }
334
335 /* check crypto seqnum. */
336 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
337
338 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
339 {
340 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
341 IF_NAME (oi),
342 ntohl(ospfh->u.crypt.crypt_seqnum),
343 ntohl(nbr->crypt_seqnum));
344 return 0;
345 }
346
347 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000348 memset(&ctx, 0, sizeof(ctx));
349 MD5Init(&ctx);
350 MD5Update(&ctx, ibuf, length);
351 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
352 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000353
354 /* compare the two */
355 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
356 {
357 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
358 IF_NAME (oi));
359 return 0;
360 }
361
362 /* save neighbor's crypt_seqnum */
363 if (nbr)
364 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
365 return 1;
366}
367
368/* This function is called from ospf_write(), it will detect the
369 authentication scheme and if it is MD5, it will change the sequence
370 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000371static int
paul718e3742002-12-13 20:15:29 +0000372ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
373{
374 struct ospf_header *ospfh;
375 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000376 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000377 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000378 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000379 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000380 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000381
382 ibuf = STREAM_DATA (op->s);
383 ospfh = (struct ospf_header *) ibuf;
384
385 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
386 return 0;
387
388 /* We do this here so when we dup a packet, we don't have to
Paul Jakma2518efd2006-08-27 06:49:29 +0000389 waste CPU rewriting other headers.
390
391 Note that quagga_time /deliberately/ is not used here */
paul9483e152002-12-13 20:55:25 +0000392 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000393 if (t > oi->crypt_seqnum)
394 oi->crypt_seqnum = t;
395 else
396 oi->crypt_seqnum++;
397
paul9483e152002-12-13 20:55:25 +0000398 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000399
400 /* Get MD5 Authentication key from auth_key list. */
401 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000402 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000403 else
404 {
paul1eb8ef22005-04-07 07:30:20 +0000405 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000406 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000407 }
408
409 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000410 memset(&ctx, 0, sizeof(ctx));
411 MD5Init(&ctx);
412 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
413 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
414 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000415
416 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000417 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000418
419 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000420 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
421
paul37163d62003-02-03 18:40:56 +0000422 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000423 /* XXX size_t */
424 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
425 (u_long)stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000426
427 return OSPF_AUTH_MD5_SIZE;
428}
429
430
paul4dadc292005-05-06 21:37:42 +0000431static int
paul718e3742002-12-13 20:15:29 +0000432ospf_ls_req_timer (struct thread *thread)
433{
434 struct ospf_neighbor *nbr;
435
436 nbr = THREAD_ARG (thread);
437 nbr->t_ls_req = NULL;
438
439 /* Send Link State Request. */
440 if (ospf_ls_request_count (nbr))
441 ospf_ls_req_send (nbr);
442
443 /* Set Link State Request retransmission timer. */
444 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
445
446 return 0;
447}
448
449void
450ospf_ls_req_event (struct ospf_neighbor *nbr)
451{
452 if (nbr->t_ls_req)
453 {
454 thread_cancel (nbr->t_ls_req);
455 nbr->t_ls_req = NULL;
456 }
457 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
458}
459
460/* Cyclic timer function. Fist registered in ospf_nbr_new () in
461 ospf_neighbor.c */
462int
463ospf_ls_upd_timer (struct thread *thread)
464{
465 struct ospf_neighbor *nbr;
466
467 nbr = THREAD_ARG (thread);
468 nbr->t_ls_upd = NULL;
469
470 /* Send Link State Update. */
471 if (ospf_ls_retransmit_count (nbr) > 0)
472 {
hasso52dc7ee2004-09-23 19:18:23 +0000473 struct list *update;
paul718e3742002-12-13 20:15:29 +0000474 struct ospf_lsdb *lsdb;
475 int i;
paul718e3742002-12-13 20:15:29 +0000476 int retransmit_interval;
477
paul718e3742002-12-13 20:15:29 +0000478 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
479
480 lsdb = &nbr->ls_rxmt;
481 update = list_new ();
482
483 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
484 {
485 struct route_table *table = lsdb->type[i].db;
486 struct route_node *rn;
487
488 for (rn = route_top (table); rn; rn = route_next (rn))
489 {
490 struct ospf_lsa *lsa;
491
492 if ((lsa = rn->info) != NULL)
493 /* Don't retransmit an LSA if we received it within
494 the last RxmtInterval seconds - this is to allow the
495 neighbour a chance to acknowledge the LSA as it may
496 have ben just received before the retransmit timer
497 fired. This is a small tweak to what is in the RFC,
498 but it will cut out out a lot of retransmit traffic
499 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000500 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000501 int2tv (retransmit_interval)) >= 0)
502 listnode_add (update, rn->info);
503 }
504 }
505
506 if (listcount (update) > 0)
507 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
508 list_delete (update);
509 }
510
511 /* Set LS Update retransmission timer. */
512 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
513
514 return 0;
515}
516
517int
518ospf_ls_ack_timer (struct thread *thread)
519{
520 struct ospf_interface *oi;
521
522 oi = THREAD_ARG (thread);
523 oi->t_ls_ack = NULL;
524
525 /* Send Link State Acknowledgment. */
526 if (listcount (oi->ls_ack) > 0)
527 ospf_ls_ack_send_delayed (oi);
528
529 /* Set LS Ack timer. */
530 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
531
532 return 0;
533}
534
paul0bfeca32004-09-24 08:07:54 +0000535#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000536static void
paul6a99f832004-09-27 12:56:30 +0000537ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000538 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000539 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000540{
541#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000542 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000543 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000544 int ret;
paul0bfeca32004-09-24 08:07:54 +0000545
546 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000547 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000548
549 /* we can but try.
550 *
551 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
552 * well as the IP_MF flag, making this all quite pointless.
553 *
554 * However, for a system on which IP_MF is left alone, and ip_id left
555 * alone or else which sets same ip_id for each fragment this might
556 * work, eg linux.
557 *
558 * XXX-TODO: It would be much nicer to have the kernel's use their
559 * existing fragmentation support to do this for us. Bugs/RFEs need to
560 * be raised against the various kernels.
561 */
562
563 /* set More Frag */
564 iph->ip_off |= IP_MF;
565
566 /* ip frag offset is expressed in units of 8byte words */
567 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
568
paul62d8e962004-11-02 20:26:45 +0000569 iovp = &msg->msg_iov[1];
570
paul0bfeca32004-09-24 08:07:54 +0000571 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
572 > maxdatasize )
573 {
574 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000575 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
576 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000577 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000578
paul18b12c32004-10-05 14:38:29 +0000579 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000580
paul6a99f832004-09-27 12:56:30 +0000581 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000582
paul18b12c32004-10-05 14:38:29 +0000583 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000584
585 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000586 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000587 " id %d, off %d, len %d, mtu %u failed with %s",
588 inet_ntoa (iph->ip_dst),
589 iph->ip_id,
590 iph->ip_off,
591 iph->ip_len,
592 mtu,
593 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000594
paul37ccfa32004-10-31 11:24:51 +0000595 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
596 {
ajs2a42e282004-12-08 18:43:03 +0000597 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000598 iph->ip_id, iph->ip_off, iph->ip_len,
599 inet_ntoa (iph->ip_dst));
600 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
601 {
ajs2a42e282004-12-08 18:43:03 +0000602 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000603 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000604 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000605 }
606 }
607
paul0bfeca32004-09-24 08:07:54 +0000608 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000609 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000610 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000611 }
612
613 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000614 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
615 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000616 iph->ip_off &= (~IP_MF);
617}
618#endif /* WANT_OSPF_WRITE_FRAGMENT */
619
ajs5dcbdf82005-03-29 16:13:49 +0000620static int
paul718e3742002-12-13 20:15:29 +0000621ospf_write (struct thread *thread)
622{
paul68980082003-03-25 05:07:42 +0000623 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000624 struct ospf_interface *oi;
625 struct ospf_packet *op;
626 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000627 struct ip iph;
628 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000629 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000630 u_char type;
631 int ret;
632 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000633 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000634#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000635 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000636#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000637 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000638#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000639
paul68980082003-03-25 05:07:42 +0000640 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000641
paul68980082003-03-25 05:07:42 +0000642 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000643 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000644 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000645 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000646
647#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000648 /* seed ipid static with low order bits of time */
649 if (ipid == 0)
650 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000651#endif /* WANT_OSPF_WRITE_FRAGMENT */
652
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000653 /* convenience - max OSPF data per packet,
654 * and reliability - not more data, than our
655 * socket can accept
656 */
657 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
658 sizeof (struct ip);
paul68b73392004-09-12 14:21:37 +0000659
paul718e3742002-12-13 20:15:29 +0000660 /* Get one packet from queue. */
661 op = ospf_fifo_head (oi->obuf);
662 assert (op);
663 assert (op->length >= OSPF_HEADER_SIZE);
664
paul68980082003-03-25 05:07:42 +0000665 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
666 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000667 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
668
paul718e3742002-12-13 20:15:29 +0000669 /* Rewrite the md5 signature & update the seq */
670 ospf_make_md5_digest (oi, op);
671
paul37ccfa32004-10-31 11:24:51 +0000672 /* Retrieve OSPF packet type. */
673 stream_set_getp (op->s, 1);
674 type = stream_getc (op->s);
675
paul68b73392004-09-12 14:21:37 +0000676 /* reset get pointer */
677 stream_set_getp (op->s, 0);
678
679 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000680 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000681
paul718e3742002-12-13 20:15:29 +0000682 sa_dst.sin_family = AF_INET;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000683#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +0000684 sa_dst.sin_len = sizeof(sa_dst);
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000685#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +0000686 sa_dst.sin_addr = op->dst;
687 sa_dst.sin_port = htons (0);
688
689 /* Set DONTROUTE flag if dst is unicast. */
690 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
691 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
692 flags = MSG_DONTROUTE;
693
paul68b73392004-09-12 14:21:37 +0000694 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
695 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000696 if ( sizeof (struct ip)
697 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000698 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
699
paul718e3742002-12-13 20:15:29 +0000700 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000701 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000702 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000703
David BÉRARD0150c9c2010-05-11 10:17:53 +0200704#if defined(__DragonFly__)
705 /*
706 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
707 */
708 iph.ip_len = htons(iph.ip_len);
709#endif
710
paul0bfeca32004-09-24 08:07:54 +0000711#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000712 /* XXX-MT: not thread-safe at all..
713 * XXX: this presumes this is only programme sending OSPF packets
714 * otherwise, no guarantee ipid will be unique
715 */
716 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000717#endif /* WANT_OSPF_WRITE_FRAGMENT */
718
paul718e3742002-12-13 20:15:29 +0000719 iph.ip_off = 0;
720 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
721 iph.ip_ttl = OSPF_VL_IP_TTL;
722 else
723 iph.ip_ttl = OSPF_IP_TTL;
724 iph.ip_p = IPPROTO_OSPFIGP;
725 iph.ip_sum = 0;
726 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
727 iph.ip_dst.s_addr = op->dst.s_addr;
728
729 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000730 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000731 msg.msg_namelen = sizeof (sa_dst);
732 msg.msg_iov = iov;
733 msg.msg_iovlen = 2;
734 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000735 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
736 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000737 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000738
739 /* Sadly we can not rely on kernels to fragment packets because of either
740 * IP_HDRINCL and/or multicast destination being set.
741 */
paul0bfeca32004-09-24 08:07:54 +0000742#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000743 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000744 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
745 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000746#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000747
748 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000749 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000750 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000751 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000752
753 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000754 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000755 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000756 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000757 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000758
paul718e3742002-12-13 20:15:29 +0000759 /* Show debug sending packet. */
760 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
761 {
762 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
763 {
ajs2a42e282004-12-08 18:43:03 +0000764 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000765 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000766 stream_set_getp (op->s, 0);
767 ospf_packet_dump (op->s);
768 }
769
ajs2a42e282004-12-08 18:43:03 +0000770 zlog_debug ("%s sent to [%s] via [%s].",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400771 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
paul718e3742002-12-13 20:15:29 +0000772 IF_NAME (oi));
773
774 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000775 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000776 }
777
778 /* Now delete packet from queue. */
779 ospf_packet_delete (oi);
780
781 if (ospf_fifo_head (oi->obuf) == NULL)
782 {
783 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000784 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000785 }
786
787 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000788 if (!list_isempty (ospf->oi_write_q))
789 ospf->t_write =
790 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000791
792 return 0;
793}
794
795/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000796static void
paul718e3742002-12-13 20:15:29 +0000797ospf_hello (struct ip *iph, struct ospf_header *ospfh,
798 struct stream * s, struct ospf_interface *oi, int size)
799{
800 struct ospf_hello *hello;
801 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000802 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000803 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000804
805 /* increment statistics. */
806 oi->hello_in++;
807
808 hello = (struct ospf_hello *) STREAM_PNT (s);
809
810 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000811 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000812 {
813 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
814 {
ajs2a42e282004-12-08 18:43:03 +0000815 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000816 "dropping.",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400817 LOOKUP (ospf_packet_type_str, ospfh->type),
pauld3241812003-09-29 12:42:39 +0000818 inet_ntoa (iph->ip_src));
819 }
820 return;
821 }
paul718e3742002-12-13 20:15:29 +0000822
paul718e3742002-12-13 20:15:29 +0000823 /* get neighbor prefix. */
824 p.family = AF_INET;
825 p.prefixlen = ip_masklen (hello->network_mask);
826 p.u.prefix4 = iph->ip_src;
827
828 /* Compare network mask. */
829 /* Checking is ignored for Point-to-Point and Virtual link. */
830 if (oi->type != OSPF_IFTYPE_POINTOPOINT
831 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
832 if (oi->address->prefixlen != p.prefixlen)
833 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000834 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
835 inet_ntoa(ospfh->router_id), IF_NAME(oi),
836 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000837 return;
838 }
839
paul718e3742002-12-13 20:15:29 +0000840 /* Compare Router Dead Interval. */
841 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
842 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000843 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
844 "(expected %u, but received %u).",
845 inet_ntoa(ospfh->router_id),
846 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000847 return;
848 }
849
paulf9ad9372005-10-21 00:45:17 +0000850 /* Compare Hello Interval - ignored if fast-hellos are set. */
851 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
852 {
853 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
854 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000855 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
856 "(expected %u, but received %u).",
857 inet_ntoa(ospfh->router_id),
858 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000859 return;
860 }
861 }
862
paul718e3742002-12-13 20:15:29 +0000863 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000864 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000865 inet_ntoa (ospfh->router_id),
866 ospf_options_dump (hello->options));
867
868 /* Compare options. */
869#define REJECT_IF_TBIT_ON 1 /* XXX */
870#ifdef REJECT_IF_TBIT_ON
871 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
872 {
873 /*
874 * This router does not support non-zero TOS.
875 * Drop this Hello packet not to establish neighbor relationship.
876 */
877 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
878 inet_ntoa (ospfh->router_id));
879 return;
880 }
881#endif /* REJECT_IF_TBIT_ON */
882
883#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000884 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000885 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
886 {
887 /*
888 * This router does know the correct usage of O-bit
889 * the bit should be set in DD packet only.
890 */
891 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
892 inet_ntoa (ospfh->router_id));
893#ifdef STRICT_OBIT_USAGE_CHECK
894 return; /* Reject this packet. */
895#else /* STRICT_OBIT_USAGE_CHECK */
896 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
897#endif /* STRICT_OBIT_USAGE_CHECK */
898 }
899#endif /* HAVE_OPAQUE_LSA */
900
901 /* new for NSSA is to ensure that NP is on and E is off */
902
paul718e3742002-12-13 20:15:29 +0000903 if (oi->area->external_routing == OSPF_AREA_NSSA)
904 {
905 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
906 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
907 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
908 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
909 {
910 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
911 return;
912 }
913 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000914 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000915 }
916 else
paul718e3742002-12-13 20:15:29 +0000917 /* The setting of the E-bit found in the Hello Packet's Options
918 field must match this area's ExternalRoutingCapability A
919 mismatch causes processing to stop and the packet to be
920 dropped. The setting of the rest of the bits in the Hello
921 Packet's Options field should be ignored. */
922 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
923 CHECK_FLAG (hello->options, OSPF_OPTION_E))
924 {
ajs3aa8d5f2004-12-11 18:00:06 +0000925 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
926 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000927 return;
928 }
paul718e3742002-12-13 20:15:29 +0000929
pauld3f0d622004-05-05 15:27:15 +0000930 /* get neighbour struct */
931 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
932
933 /* neighbour must be valid, ospf_nbr_get creates if none existed */
934 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000935
936 old_state = nbr->state;
937
938 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000939 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000940
941 /* RFC2328 Section 9.5.1
942 If the router is not eligible to become Designated Router,
943 (snip) It must also send an Hello Packet in reply to an
944 Hello Packet received from any eligible neighbor (other than
945 the current Designated Router and Backup Designated Router). */
946 if (oi->type == OSPF_IFTYPE_NBMA)
947 if (PRIORITY(oi) == 0 && hello->priority > 0
948 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
949 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
950 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
951 OSPF_HELLO_REPLY_DELAY);
952
953 /* on NBMA network type, it happens to receive bidirectional Hello packet
954 without advance 1-Way Received event.
955 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
956 if (oi->type == OSPF_IFTYPE_NBMA &&
957 (old_state == NSM_Down || old_state == NSM_Attempt))
958 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000959 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000960 nbr->priority = hello->priority;
961 nbr->d_router = hello->d_router;
962 nbr->bd_router = hello->bd_router;
963 return;
964 }
965
paul68980082003-03-25 05:07:42 +0000966 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000967 size - OSPF_HELLO_MIN_SIZE))
968 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000969 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000970 nbr->options |= hello->options;
971 }
972 else
973 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000974 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000975 /* Set neighbor information. */
976 nbr->priority = hello->priority;
977 nbr->d_router = hello->d_router;
978 nbr->bd_router = hello->bd_router;
979 return;
980 }
981
982 /* If neighbor itself declares DR and no BDR exists,
983 cause event BackupSeen */
984 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
985 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
986 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
987
988 /* neighbor itself declares BDR. */
989 if (oi->state == ISM_Waiting &&
990 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
991 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
992
993 /* had not previously. */
994 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
995 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
996 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
997 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
998 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
999
1000 /* had not previously. */
1001 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
1002 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
1003 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
1004 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
1005 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1006
1007 /* Neighbor priority check. */
1008 if (nbr->priority >= 0 && nbr->priority != hello->priority)
1009 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1010
1011 /* Set neighbor information. */
1012 nbr->priority = hello->priority;
1013 nbr->d_router = hello->d_router;
1014 nbr->bd_router = hello->bd_router;
1015}
1016
1017/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +00001018static void
paul718e3742002-12-13 20:15:29 +00001019ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1020 struct ospf_db_desc *dd)
1021{
1022 nbr->last_recv.flags = dd->flags;
1023 nbr->last_recv.options = dd->options;
1024 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1025}
1026
1027/* Process rest of DD packet. */
1028static void
1029ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1030 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1031 u_int16_t size)
1032{
1033 struct ospf_lsa *new, *find;
1034 struct lsa_header *lsah;
1035
paul9985f832005-02-09 15:51:56 +00001036 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001037 for (size -= OSPF_DB_DESC_MIN_SIZE;
1038 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1039 {
1040 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001041 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001042
1043 /* Unknown LS type. */
1044 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1045 {
ajsbec595a2004-11-30 22:38:43 +00001046 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001047 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1048 return;
1049 }
1050
1051#ifdef HAVE_OPAQUE_LSA
1052 if (IS_OPAQUE_LSA (lsah->type)
1053 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1054 {
1055 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1056 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1057 return;
1058 }
1059#endif /* HAVE_OPAQUE_LSA */
1060
1061 switch (lsah->type)
1062 {
1063 case OSPF_AS_EXTERNAL_LSA:
1064#ifdef HAVE_OPAQUE_LSA
1065 case OSPF_OPAQUE_AS_LSA:
1066#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001067 /* Check for stub area. Reject if AS-External from stub but
1068 allow if from NSSA. */
1069 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001070 {
1071 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1072 lsah->type, inet_ntoa (lsah->id),
1073 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1074 "STUB" : "NSSA");
1075 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1076 return;
1077 }
1078 break;
1079 default:
1080 break;
1081 }
1082
1083 /* Create LS-request object. */
1084 new = ospf_ls_request_new (lsah);
1085
1086 /* Lookup received LSA, then add LS request list. */
1087 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001088
1089 /* ospf_lsa_more_recent is fine with NULL pointers */
1090 switch (ospf_lsa_more_recent (find, new))
1091 {
1092 case -1:
1093 /* Neighbour has a more recent LSA, we must request it */
1094 ospf_ls_request_add (nbr, new);
1095 case 0:
1096 /* If we have a copy of this LSA, it's either less recent
1097 * and we're requesting it from neighbour (the case above), or
1098 * it's as recent and we both have same copy (this case).
1099 *
1100 * In neither of these two cases is there any point in
1101 * describing our copy of the LSA to the neighbour in a
1102 * DB-Summary packet, if we're still intending to do so.
1103 *
1104 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1105 * backward compatible optimisation to OSPF DB Exchange /
1106 * DB Description process implemented here.
1107 */
1108 if (find)
1109 ospf_lsdb_delete (&nbr->db_sum, find);
1110 ospf_lsa_discard (new);
1111 break;
1112 default:
1113 /* We have the more recent copy, nothing specific to do:
1114 * - no need to request neighbours stale copy
1115 * - must leave DB summary list copy alone
1116 */
1117 if (IS_DEBUG_OSPF_EVENT)
1118 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1119 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1120 ospf_lsa_discard (new);
1121 }
paul718e3742002-12-13 20:15:29 +00001122 }
1123
1124 /* Master */
1125 if (IS_SET_DD_MS (nbr->dd_flags))
1126 {
1127 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001128
1129 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001130 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1131 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1132 else
paul718e3742002-12-13 20:15:29 +00001133 ospf_db_desc_send (nbr);
1134 }
1135 /* Slave */
1136 else
1137 {
1138 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1139
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001140 /* Send DD packet in reply.
1141 *
1142 * Must be done to acknowledge the Master's DD, regardless of
1143 * whether we have more LSAs ourselves to describe.
1144 *
1145 * This function will clear the 'More' bit, if after this DD
1146 * we have no more LSAs to describe to the master..
1147 */
paul718e3742002-12-13 20:15:29 +00001148 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001149
1150 /* Slave can raise ExchangeDone now, if master is also done */
1151 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1152 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001153 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001154
paul718e3742002-12-13 20:15:29 +00001155 /* Save received neighbor values from DD. */
1156 ospf_db_desc_save_current (nbr, dd);
1157}
1158
paul4dadc292005-05-06 21:37:42 +00001159static int
paul718e3742002-12-13 20:15:29 +00001160ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1161{
1162 /* Is DD duplicated? */
1163 if (dd->options == nbr->last_recv.options &&
1164 dd->flags == nbr->last_recv.flags &&
1165 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1166 return 1;
1167
1168 return 0;
1169}
1170
1171/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001172static void
paul718e3742002-12-13 20:15:29 +00001173ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1174 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1175{
1176 struct ospf_db_desc *dd;
1177 struct ospf_neighbor *nbr;
1178
1179 /* Increment statistics. */
1180 oi->db_desc_in++;
1181
1182 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001183
pauld3f0d622004-05-05 15:27:15 +00001184 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001185 if (nbr == NULL)
1186 {
1187 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1188 inet_ntoa (ospfh->router_id));
1189 return;
1190 }
1191
1192 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001193 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1194 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001195 {
ajs3aa8d5f2004-12-11 18:00:06 +00001196 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1197 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1198 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001199 return;
1200 }
1201
pauld363df22003-06-19 00:26:34 +00001202 /*
1203 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1204 * required. In fact at least JunOS sends DD packets with P bit clear.
1205 * Until proper solution is developped, this hack should help.
1206 *
1207 * Update: According to the RFCs, N bit is specified /only/ for Hello
1208 * options, unfortunately its use in DD options is not specified. Hence some
1209 * implementations follow E-bit semantics and set it in DD options, and some
1210 * treat it as unspecified and hence follow the directive "default for
1211 * options is clear", ie unset.
1212 *
1213 * Reset the flag, as ospfd follows E-bit semantics.
1214 */
1215 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1216 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1217 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1218 {
1219 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001220 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001221 inet_ntoa (nbr->router_id) );
1222 SET_FLAG (dd->options, OSPF_OPTION_NP);
1223 }
pauld363df22003-06-19 00:26:34 +00001224
paul718e3742002-12-13 20:15:29 +00001225#ifdef REJECT_IF_TBIT_ON
1226 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1227 {
1228 /*
1229 * In Hello protocol, optional capability must have checked
1230 * to prevent this T-bit enabled router be my neighbor.
1231 */
1232 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1233 return;
1234 }
1235#endif /* REJECT_IF_TBIT_ON */
1236
1237#ifdef HAVE_OPAQUE_LSA
1238 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001239 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001240 {
1241 /*
1242 * This node is not configured to handle O-bit, for now.
1243 * Clear it to ignore unsupported capability proposed by neighbor.
1244 */
1245 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1246 }
1247#endif /* HAVE_OPAQUE_LSA */
1248
Paul Jakma57c5c652010-01-07 06:12:53 +00001249 /* Add event to thread. */
1250 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1251
paul718e3742002-12-13 20:15:29 +00001252 /* Process DD packet by neighbor status. */
1253 switch (nbr->state)
1254 {
1255 case NSM_Down:
1256 case NSM_Attempt:
1257 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001258 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001259 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001260 LOOKUP (ospf_nsm_state_msg, nbr->state));
1261 break;
1262 case NSM_Init:
1263 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1264 /* If the new state is ExStart, the processing of the current
1265 packet should then continue in this new state by falling
1266 through to case ExStart below. */
1267 if (nbr->state != NSM_ExStart)
1268 break;
1269 case NSM_ExStart:
1270 /* Initial DBD */
1271 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1272 (size == OSPF_DB_DESC_MIN_SIZE))
1273 {
paul68980082003-03-25 05:07:42 +00001274 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001275 {
1276 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001277 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001278 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001279 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001280
1281 /* Reset I/MS */
1282 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001283 }
1284 else
1285 {
1286 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001287 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001288 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001289 break;
1290 }
1291 }
1292 /* Ack from the Slave */
1293 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1294 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001295 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001296 {
ajs17eaa722004-12-29 21:04:48 +00001297 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001298 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001299 /* Reset I, leaving MS */
1300 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001301 }
1302 else
1303 {
ajs3aa8d5f2004-12-11 18:00:06 +00001304 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1305 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001306 break;
1307 }
1308
1309 /* This is where the real Options are saved */
1310 nbr->options = dd->options;
1311
1312#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001313 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001314 {
1315 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001316 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001317 inet_ntoa (nbr->router_id),
1318 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1319
1320 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1321 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1322 {
paul6d452762005-11-03 11:15:44 +00001323 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1324 "Opaque-LSAs cannot be reliably advertised "
1325 "in this network.",
1326 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001327 /* This situation is undesirable, but not a real error. */
1328 }
1329 }
1330#endif /* HAVE_OPAQUE_LSA */
1331
1332 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1333
1334 /* continue processing rest of packet. */
1335 ospf_db_desc_proc (s, oi, nbr, dd, size);
1336 break;
1337 case NSM_Exchange:
1338 if (ospf_db_desc_is_dup (dd, nbr))
1339 {
1340 if (IS_SET_DD_MS (nbr->dd_flags))
1341 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001342 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001343 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001344 else
1345 /* Slave: cause to retransmit the last Database Description. */
1346 {
paul6d452762005-11-03 11:15:44 +00001347 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001348 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001349 ospf_db_desc_resend (nbr);
1350 }
1351 break;
1352 }
1353
1354 /* Otherwise DD packet should be checked. */
1355 /* Check Master/Slave bit mismatch */
1356 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1357 {
ajs3aa8d5f2004-12-11 18:00:06 +00001358 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1359 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001360 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1361 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001362 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001363 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001364 break;
1365 }
1366
1367 /* Check initialize bit is set. */
1368 if (IS_SET_DD_I (dd->flags))
1369 {
paul6d452762005-11-03 11:15:44 +00001370 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001371 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001372 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1373 break;
1374 }
1375
1376 /* Check DD Options. */
1377 if (dd->options != nbr->options)
1378 {
1379#ifdef ORIGINAL_CODING
1380 /* Save the new options for debugging */
1381 nbr->options = dd->options;
1382#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001383 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1384 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001385 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1386 break;
1387 }
1388
1389 /* Check DD sequence number. */
1390 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1391 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1392 (!IS_SET_DD_MS (nbr->dd_flags) &&
1393 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1394 {
ajs3aa8d5f2004-12-11 18:00:06 +00001395 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1396 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001397 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1398 break;
1399 }
1400
1401 /* Continue processing rest of packet. */
1402 ospf_db_desc_proc (s, oi, nbr, dd, size);
1403 break;
1404 case NSM_Loading:
1405 case NSM_Full:
1406 if (ospf_db_desc_is_dup (dd, nbr))
1407 {
1408 if (IS_SET_DD_MS (nbr->dd_flags))
1409 {
1410 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001411 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1412 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001413 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001414 break;
1415 }
1416 else
1417 {
1418 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001419 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001420 t = tv_sub (now, nbr->last_send_ts);
1421 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1422 {
1423 /* In states Loading and Full the slave must resend
1424 its last Database Description packet in response to
1425 duplicate Database Description packets received
1426 from the master. For this reason the slave must
1427 wait RouterDeadInterval seconds before freeing the
1428 last Database Description packet. Reception of a
1429 Database Description packet from the master after
1430 this interval will generate a SeqNumberMismatch
1431 neighbor event. RFC2328 Section 10.8 */
1432 ospf_db_desc_resend (nbr);
1433 break;
1434 }
1435 }
1436 }
1437
1438 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1439 break;
1440 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001441 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1442 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001443 break;
1444 }
1445}
1446
1447#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1448
1449/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001450static void
paul718e3742002-12-13 20:15:29 +00001451ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1452 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1453{
1454 struct ospf_neighbor *nbr;
1455 u_int32_t ls_type;
1456 struct in_addr ls_id;
1457 struct in_addr adv_router;
1458 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001459 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001460 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001461
1462 /* Increment statistics. */
1463 oi->ls_req_in++;
1464
pauld3f0d622004-05-05 15:27:15 +00001465 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001466 if (nbr == NULL)
1467 {
1468 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1469 inet_ntoa (ospfh->router_id));
1470 return;
1471 }
1472
Paul Jakma57c5c652010-01-07 06:12:53 +00001473 /* Add event to thread. */
1474 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1475
paul718e3742002-12-13 20:15:29 +00001476 /* Neighbor State should be Exchange or later. */
1477 if (nbr->state != NSM_Exchange &&
1478 nbr->state != NSM_Loading &&
1479 nbr->state != NSM_Full)
1480 {
ajsbec595a2004-11-30 22:38:43 +00001481 zlog_warn ("Link State Request received from %s: "
1482 "Neighbor state is %s, packet discarded.",
1483 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001484 LOOKUP (ospf_nsm_state_msg, nbr->state));
1485 return;
1486 }
1487
1488 /* Send Link State Update for ALL requested LSAs. */
1489 ls_upd = list_new ();
1490 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1491
1492 while (size >= OSPF_LSA_KEY_SIZE)
1493 {
1494 /* Get one slice of Link State Request. */
1495 ls_type = stream_getl (s);
1496 ls_id.s_addr = stream_get_ipv4 (s);
1497 adv_router.s_addr = stream_get_ipv4 (s);
1498
1499 /* Verify LSA type. */
1500 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1501 {
1502 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1503 list_delete (ls_upd);
1504 return;
1505 }
1506
1507 /* Search proper LSA in LSDB. */
1508 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1509 if (find == NULL)
1510 {
1511 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1512 list_delete (ls_upd);
1513 return;
1514 }
1515
gdt86f1fd92005-01-10 14:20:43 +00001516 /* Packet overflows MTU size, send immediately. */
1517 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001518 {
1519 if (oi->type == OSPF_IFTYPE_NBMA)
1520 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1521 else
1522 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1523
1524 /* Only remove list contents. Keep ls_upd. */
1525 list_delete_all_node (ls_upd);
1526
1527 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1528 }
1529
1530 /* Append LSA to update list. */
1531 listnode_add (ls_upd, find);
1532 length += ntohs (find->data->length);
1533
1534 size -= OSPF_LSA_KEY_SIZE;
1535 }
1536
1537 /* Send rest of Link State Update. */
1538 if (listcount (ls_upd) > 0)
1539 {
1540 if (oi->type == OSPF_IFTYPE_NBMA)
1541 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1542 else
1543 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1544
1545 list_delete (ls_upd);
1546 }
1547 else
1548 list_free (ls_upd);
1549}
1550
1551/* Get the list of LSAs from Link State Update packet.
1552 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001553static struct list *
paul718e3742002-12-13 20:15:29 +00001554ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1555 struct ospf_interface *oi, size_t size)
1556{
1557 u_int16_t count, sum;
1558 u_int32_t length;
1559 struct lsa_header *lsah;
1560 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001561 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001562
1563 lsas = list_new ();
1564
1565 count = stream_getl (s);
1566 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1567
1568 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001569 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001570 {
1571 lsah = (struct lsa_header *) STREAM_PNT (s);
1572 length = ntohs (lsah->length);
1573
1574 if (length > size)
1575 {
1576 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1577 break;
1578 }
1579
1580 /* Validate the LSA's LS checksum. */
1581 sum = lsah->checksum;
1582 if (sum != ospf_lsa_checksum (lsah))
1583 {
Jaroslav Fojtik223da1a2011-12-11 18:22:16 +04001584 /* (bug #685) more details in a one-line message make it possible
1585 * to identify problem source on the one hand and to have a better
1586 * chance to compress repeated messages in syslog on the other */
1587 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1588 sum, lsah->checksum, inet_ntoa (lsah->id),
1589 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1590 inet_ntoa (lsah->adv_router));
paul718e3742002-12-13 20:15:29 +00001591 continue;
1592 }
1593
1594 /* Examine the LSA's LS type. */
1595 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1596 {
1597 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1598 continue;
1599 }
1600
1601 /*
1602 * What if the received LSA's age is greater than MaxAge?
1603 * Treat it as a MaxAge case -- endo.
1604 */
1605 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1606 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1607
1608#ifdef HAVE_OPAQUE_LSA
1609 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1610 {
1611#ifdef STRICT_OBIT_USAGE_CHECK
1612 if ((IS_OPAQUE_LSA(lsah->type) &&
1613 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1614 || (! IS_OPAQUE_LSA(lsah->type) &&
1615 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1616 {
1617 /*
1618 * This neighbor must know the exact usage of O-bit;
1619 * the bit will be set in Type-9,10,11 LSAs only.
1620 */
1621 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1622 continue;
1623 }
1624#endif /* STRICT_OBIT_USAGE_CHECK */
1625
1626 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1627 if (lsah->type == OSPF_OPAQUE_AS_LSA
1628 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1629 {
1630 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001631 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 +00001632 continue;
1633 }
1634 }
1635 else if (IS_OPAQUE_LSA(lsah->type))
1636 {
1637 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1638 continue;
1639 }
1640#endif /* HAVE_OPAQUE_LSA */
1641
1642 /* Create OSPF LSA instance. */
1643 lsa = ospf_lsa_new ();
1644
1645 /* We may wish to put some error checking if type NSSA comes in
1646 and area not in NSSA mode */
1647 switch (lsah->type)
1648 {
1649 case OSPF_AS_EXTERNAL_LSA:
1650#ifdef HAVE_OPAQUE_LSA
1651 case OSPF_OPAQUE_AS_LSA:
1652 lsa->area = NULL;
1653 break;
1654 case OSPF_OPAQUE_LINK_LSA:
1655 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1656 /* Fallthrough */
1657#endif /* HAVE_OPAQUE_LSA */
1658 default:
1659 lsa->area = oi->area;
1660 break;
1661 }
1662
1663 lsa->data = ospf_lsa_data_new (length);
1664 memcpy (lsa->data, lsah, length);
1665
1666 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001667 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001668 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1669 listnode_add (lsas, lsa);
1670 }
1671
1672 return lsas;
1673}
1674
1675/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001676static void
hasso52dc7ee2004-09-23 19:18:23 +00001677ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001678{
paul1eb8ef22005-04-07 07:30:20 +00001679 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001680 struct ospf_lsa *lsa;
1681
paul1eb8ef22005-04-07 07:30:20 +00001682 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1683 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001684
1685 list_delete (lsas);
1686}
1687
1688/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001689static void
paul718e3742002-12-13 20:15:29 +00001690ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1691 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1692{
1693 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001694 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001695 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001696 struct ospf_lsa *lsa = NULL;
1697 /* unsigned long ls_req_found = 0; */
1698
1699 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1700
1701 /* Increment statistics. */
1702 oi->ls_upd_in++;
1703
1704 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001705 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001706 if (nbr == NULL)
1707 {
1708 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1709 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1710 return;
1711 }
1712
Paul Jakma57c5c652010-01-07 06:12:53 +00001713 /* Add event to thread. */
1714 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1715
paul718e3742002-12-13 20:15:29 +00001716 /* Check neighbor state. */
1717 if (nbr->state < NSM_Exchange)
1718 {
ajs3aa8d5f2004-12-11 18:00:06 +00001719 zlog_warn ("Link State Update: "
1720 "Neighbor[%s] state %s is less than Exchange",
1721 inet_ntoa (ospfh->router_id),
1722 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001723 return;
1724 }
1725
1726 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1727 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1728 * of section 13.
1729 */
1730 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1731
1732#ifdef HAVE_OPAQUE_LSA
1733 /*
paul718e3742002-12-13 20:15:29 +00001734 * If self-originated Opaque-LSAs that have flooded before restart
1735 * are contained in the received LSUpd message, corresponding LSReq
1736 * messages to be sent may have to be modified.
1737 * To eliminate possible race conditions such that flushing and normal
1738 * updating for the same LSA would take place alternately, this trick
1739 * must be done before entering to the loop below.
1740 */
paul69310a62005-05-11 18:09:59 +00001741 /* XXX: Why is this Opaque specific? Either our core code is deficient
1742 * and this should be fixed generally, or Opaque is inventing strawman
1743 * problems */
paul718e3742002-12-13 20:15:29 +00001744 ospf_opaque_adjust_lsreq (nbr, lsas);
1745#endif /* HAVE_OPAQUE_LSA */
1746
1747#define DISCARD_LSA(L,N) {\
1748 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001749 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 +00001750 ospf_lsa_discard (L); \
1751 continue; }
1752
1753 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001754 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001755 {
1756 struct ospf_lsa *ls_ret, *current;
1757 int ret = 1;
1758
paul718e3742002-12-13 20:15:29 +00001759 if (IS_DEBUG_OSPF_NSSA)
1760 {
1761 char buf1[INET_ADDRSTRLEN];
1762 char buf2[INET_ADDRSTRLEN];
1763 char buf3[INET_ADDRSTRLEN];
1764
ajs2a42e282004-12-08 18:43:03 +00001765 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001766 lsa->data->type,
1767 inet_ntop (AF_INET, &ospfh->router_id,
1768 buf1, INET_ADDRSTRLEN),
1769 inet_ntop (AF_INET, &lsa->data->id,
1770 buf2, INET_ADDRSTRLEN),
1771 inet_ntop (AF_INET, &lsa->data->adv_router,
1772 buf3, INET_ADDRSTRLEN));
1773 }
paul718e3742002-12-13 20:15:29 +00001774
1775 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1776
1777 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1778
1779 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1780
1781 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1782
1783 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1784
1785 /* Do take in Type-7's if we are an NSSA */
1786
1787 /* If we are also an ABR, later translate them to a Type-5 packet */
1788
1789 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1790 translate them to a separate Type-5 packet. */
1791
1792 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1793 /* Reject from STUB or NSSA */
1794 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1795 {
paul718e3742002-12-13 20:15:29 +00001796 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001797 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001798 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001799 }
1800
paul718e3742002-12-13 20:15:29 +00001801 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1802 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1803 {
paul718e3742002-12-13 20:15:29 +00001804 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001805 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001806 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001807 }
paul718e3742002-12-13 20:15:29 +00001808
1809 /* Find the LSA in the current database. */
1810
1811 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1812
1813 /* If the LSA's LS age is equal to MaxAge, and there is currently
1814 no instance of the LSA in the router's link state database,
1815 and none of router's neighbors are in states Exchange or Loading,
1816 then take the following actions. */
1817
1818 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001819 (ospf_nbr_count (oi, NSM_Exchange) +
1820 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001821 {
1822 /* Response Link State Acknowledgment. */
1823 ospf_ls_ack_send (nbr, lsa);
1824
1825 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001826 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1827 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001828 DISCARD_LSA (lsa, 3);
1829 }
1830
1831#ifdef HAVE_OPAQUE_LSA
1832 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001833 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001834 {
1835 /*
1836 * Even if initial flushing seems to be completed, there might
1837 * be a case that self-originated LSA with MaxAge still remain
1838 * in the routing domain.
1839 * Just send an LSAck message to cease retransmission.
1840 */
1841 if (IS_LSA_MAXAGE (lsa))
1842 {
1843 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1844 ospf_ls_ack_send (nbr, lsa);
1845 ospf_lsa_discard (lsa);
1846
1847 if (current != NULL && ! IS_LSA_MAXAGE (current))
1848 ospf_opaque_lsa_refresh_schedule (current);
1849 continue;
1850 }
1851
1852 /*
1853 * If an instance of self-originated Opaque-LSA is not found
1854 * in the LSDB, there are some possible cases here.
1855 *
1856 * 1) This node lost opaque-capability after restart.
1857 * 2) Else, a part of opaque-type is no more supported.
1858 * 3) Else, a part of opaque-id is no more supported.
1859 *
1860 * Anyway, it is still this node's responsibility to flush it.
1861 * Otherwise, the LSA instance remains in the routing domain
1862 * until its age reaches to MaxAge.
1863 */
paul69310a62005-05-11 18:09:59 +00001864 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001865 if (current == NULL)
1866 {
1867 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001868 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1869 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001870
1871 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001872
1873 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1874 ospf_ls_ack_send (nbr, lsa);
1875
paul718e3742002-12-13 20:15:29 +00001876 continue;
1877 }
1878 }
1879#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001880
hassocb05eb22004-02-11 21:10:19 +00001881 /* It might be happen that received LSA is self-originated network LSA, but
1882 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1883 * Link State ID is one of the router's own IP interface addresses but whose
1884 * Advertising Router is not equal to the router's own Router ID
1885 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1886 */
1887
1888 if(lsa->data->type == OSPF_NETWORK_LSA)
1889 {
paul1eb8ef22005-04-07 07:30:20 +00001890 struct listnode *oinode, *oinnode;
1891 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001892 int Flag = 0;
1893
paul1eb8ef22005-04-07 07:30:20 +00001894 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001895 {
hassocb05eb22004-02-11 21:10:19 +00001896 if(out_if == NULL)
1897 break;
1898
1899 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1900 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1901 {
1902 if(out_if->network_lsa_self)
1903 {
1904 ospf_lsa_flush_area(lsa,out_if->area);
1905 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001906 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001907 lsa, (int) lsa->data->type);
1908 ospf_lsa_discard (lsa);
1909 Flag = 1;
1910 }
1911 break;
1912 }
1913 }
1914 if(Flag)
1915 continue;
1916 }
paul718e3742002-12-13 20:15:29 +00001917
1918 /* (5) Find the instance of this LSA that is currently contained
1919 in the router's link state database. If there is no
1920 database copy, or the received LSA is more recent than
1921 the database copy the following steps must be performed. */
1922
1923 if (current == NULL ||
1924 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1925 {
1926 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001927 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001928 DISCARD_LSA (lsa, 4);
1929 continue;
1930 }
1931
1932 /* (6) Else, If there is an instance of the LSA on the sending
1933 neighbor's Link state request list, an error has occurred in
1934 the Database Exchange process. In this case, restart the
1935 Database Exchange process by generating the neighbor event
1936 BadLSReq for the sending neighbor and stop processing the
1937 Link State Update packet. */
1938
1939 if (ospf_ls_request_lookup (nbr, lsa))
1940 {
1941 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001942 zlog_warn("LSA[%s] instance exists on Link state request list",
1943 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001944
1945 /* Clean list of LSAs. */
1946 ospf_upd_list_clean (lsas);
1947 /* this lsa is not on lsas list already. */
1948 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001949 return;
1950 }
1951
1952 /* If the received LSA is the same instance as the database copy
1953 (i.e., neither one is more recent) the following two steps
1954 should be performed: */
1955
1956 if (ret == 0)
1957 {
1958 /* If the LSA is listed in the Link state retransmission list
1959 for the receiving adjacency, the router itself is expecting
1960 an acknowledgment for this LSA. The router should treat the
1961 received LSA as an acknowledgment by removing the LSA from
1962 the Link state retransmission list. This is termed an
1963 "implied acknowledgment". */
1964
1965 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1966
1967 if (ls_ret != NULL)
1968 {
1969 ospf_ls_retransmit_delete (nbr, ls_ret);
1970
1971 /* Delayed acknowledgment sent if advertisement received
1972 from Designated Router, otherwise do nothing. */
1973 if (oi->state == ISM_Backup)
1974 if (NBR_IS_DR (nbr))
1975 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1976
1977 DISCARD_LSA (lsa, 5);
1978 }
1979 else
1980 /* Acknowledge the receipt of the LSA by sending a
1981 Link State Acknowledgment packet back out the receiving
1982 interface. */
1983 {
1984 ospf_ls_ack_send (nbr, lsa);
1985 DISCARD_LSA (lsa, 6);
1986 }
1987 }
1988
1989 /* The database copy is more recent. If the database copy
1990 has LS age equal to MaxAge and LS sequence number equal to
1991 MaxSequenceNumber, simply discard the received LSA without
1992 acknowledging it. (In this case, the LSA's LS sequence number is
1993 wrapping, and the MaxSequenceNumber LSA must be completely
1994 flushed before any new LSA instance can be introduced). */
1995
1996 else if (ret > 0) /* Database copy is more recent */
1997 {
1998 if (IS_LSA_MAXAGE (current) &&
1999 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
2000 {
2001 DISCARD_LSA (lsa, 7);
2002 }
2003 /* Otherwise, as long as the database copy has not been sent in a
2004 Link State Update within the last MinLSArrival seconds, send the
2005 database copy back to the sending neighbor, encapsulated within
2006 a Link State Update Packet. The Link State Update Packet should
2007 be sent directly to the neighbor. In so doing, do not put the
2008 database copy of the LSA on the neighbor's link state
2009 retransmission list, and do not acknowledge the received (less
2010 recent) LSA instance. */
2011 else
2012 {
2013 struct timeval now;
2014
Paul Jakma2518efd2006-08-27 06:49:29 +00002015 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00002016
2017 if (tv_cmp (tv_sub (now, current->tv_orig),
Paul Jakma2c9f8e32010-01-11 16:22:12 +00002018 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
paul718e3742002-12-13 20:15:29 +00002019 /* Trap NSSA type later.*/
2020 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2021 DISCARD_LSA (lsa, 8);
2022 }
2023 }
2024 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002025#undef DISCARD_LSA
2026
paul718e3742002-12-13 20:15:29 +00002027 assert (listcount (lsas) == 0);
2028 list_delete (lsas);
2029}
2030
2031/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002032static void
paul718e3742002-12-13 20:15:29 +00002033ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2034 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2035{
2036 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002037
paul718e3742002-12-13 20:15:29 +00002038 /* increment statistics. */
2039 oi->ls_ack_in++;
2040
pauld3f0d622004-05-05 15:27:15 +00002041 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002042 if (nbr == NULL)
2043 {
2044 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2045 inet_ntoa (ospfh->router_id));
2046 return;
2047 }
2048
Paul Jakma57c5c652010-01-07 06:12:53 +00002049 /* Add event to thread. */
2050 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2051
paul718e3742002-12-13 20:15:29 +00002052 if (nbr->state < NSM_Exchange)
2053 {
ajs3aa8d5f2004-12-11 18:00:06 +00002054 zlog_warn ("Link State Acknowledgment: "
2055 "Neighbor[%s] state %s is less than Exchange",
2056 inet_ntoa (ospfh->router_id),
2057 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002058 return;
2059 }
paul69310a62005-05-11 18:09:59 +00002060
paul718e3742002-12-13 20:15:29 +00002061 while (size >= OSPF_LSA_HEADER_SIZE)
2062 {
2063 struct ospf_lsa *lsa, *lsr;
2064
2065 lsa = ospf_lsa_new ();
2066 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2067
2068 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2069 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002070 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002071
2072 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2073 {
2074 lsa->data = NULL;
2075 ospf_lsa_discard (lsa);
2076 continue;
2077 }
2078
2079 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2080
2081 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2082 {
2083#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002084 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002085 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002086#endif /* HAVE_OPAQUE_LSA */
2087
2088 ospf_ls_retransmit_delete (nbr, lsr);
2089 }
2090
2091 lsa->data = NULL;
2092 ospf_lsa_discard (lsa);
2093 }
2094
paul718e3742002-12-13 20:15:29 +00002095 return;
paul718e3742002-12-13 20:15:29 +00002096}
2097
ajs038163f2005-02-17 19:55:59 +00002098static struct stream *
ajs5c333492005-02-23 15:43:01 +00002099ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002100{
2101 int ret;
ajs5c333492005-02-23 15:43:01 +00002102 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002103 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002104 unsigned int ifindex = 0;
2105 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002106 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002107 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002108 struct msghdr msgh;
2109
paul68defd62004-09-27 07:27:13 +00002110 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002111 msgh.msg_iov = &iov;
2112 msgh.msg_iovlen = 1;
2113 msgh.msg_control = (caddr_t) buff;
2114 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002115
ajs5c333492005-02-23 15:43:01 +00002116 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2117 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002118 {
ajs5c333492005-02-23 15:43:01 +00002119 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2120 return NULL;
2121 }
paul69310a62005-05-11 18:09:59 +00002122 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002123 {
2124 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2125 "(ip header size is %u)",
2126 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002127 return NULL;
2128 }
paul18b12c32004-10-05 14:38:29 +00002129
ajs5c333492005-02-23 15:43:01 +00002130 /* Note that there should not be alignment problems with this assignment
2131 because this is at the beginning of the stream data buffer. */
2132 iph = (struct ip *) STREAM_DATA(ibuf);
2133 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002134
ajs5c333492005-02-23 15:43:01 +00002135 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002136
Dmitrij Tejblumde5ccb92011-12-12 20:30:10 +04002137#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
paul718e3742002-12-13 20:15:29 +00002138 /*
2139 * Kernel network code touches incoming IP header parameters,
2140 * before protocol specific processing.
2141 *
2142 * 1) Convert byteorder to host representation.
2143 * --> ip_len, ip_id, ip_off
2144 *
2145 * 2) Adjust ip_len to strip IP header size!
2146 * --> If user process receives entire IP packet via RAW
2147 * socket, it must consider adding IP header size to
2148 * the "ip_len" field of "ip" structure.
2149 *
2150 * For more details, see <netinet/ip_input.c>.
2151 */
ajs5c333492005-02-23 15:43:01 +00002152 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002153#endif
2154
David BÉRARD0150c9c2010-05-11 10:17:53 +02002155#if defined(__DragonFly__)
2156 /*
2157 * in DragonFly's raw socket, ip_len/ip_off are read
2158 * in network byte order.
2159 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2160 */
2161 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2162#endif
2163
paul863082d2004-08-19 04:43:43 +00002164 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002165
2166 *ifp = if_lookup_by_index (ifindex);
2167
2168 if (ret != ip_len)
2169 {
ajs5c333492005-02-23 15:43:01 +00002170 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2171 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002172 return NULL;
2173 }
2174
2175 return ibuf;
2176}
2177
paul4dadc292005-05-06 21:37:42 +00002178static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002179ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002180 struct ip *iph, struct ospf_header *ospfh)
2181{
2182 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002183 struct ospf_vl_data *vl_data;
2184 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002185 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002186
2187 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2188 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002189 return NULL;
paul718e3742002-12-13 20:15:29 +00002190
pauld3f0d622004-05-05 15:27:15 +00002191 /* look for local OSPF interface matching the destination
2192 * to determine Area ID. We presume therefore the destination address
2193 * is unique, or at least (for "unnumbered" links), not used in other
2194 * areas
2195 */
2196 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2197 iph->ip_dst)) == NULL)
2198 return NULL;
paul718e3742002-12-13 20:15:29 +00002199
paul1eb8ef22005-04-07 07:30:20 +00002200 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002201 {
paul020709f2003-04-04 02:44:16 +00002202 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002203 if (!vl_area)
2204 continue;
2205
2206 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2207 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2208 {
2209 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002210 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002211 IF_NAME (vl_data->vl_oi));
2212 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2213 {
2214 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002215 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002216 return NULL;
2217 }
2218
2219 return vl_data->vl_oi;
2220 }
2221 }
2222
2223 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002224 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002225
pauld3f0d622004-05-05 15:27:15 +00002226 return NULL;
paul718e3742002-12-13 20:15:29 +00002227}
2228
Paul Jakmaf63f06d2011-04-08 12:44:43 +01002229static int
paul718e3742002-12-13 20:15:29 +00002230ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2231{
2232 /* Check match the Area ID of the receiving interface. */
2233 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2234 return 1;
2235
2236 return 0;
2237}
2238
2239/* Unbound socket will accept any Raw IP packets if proto is matched.
2240 To prevent it, compare src IP address and i/f address with masking
2241 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002242static int
paul718e3742002-12-13 20:15:29 +00002243ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2244{
2245 struct in_addr mask, me, him;
2246
2247 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2248 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2249 return 1;
2250
2251 masklen2ip (oi->address->prefixlen, &mask);
2252
2253 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2254 him.s_addr = ip_src.s_addr & mask.s_addr;
2255
2256 if (IPV4_ADDR_SAME (&me, &him))
2257 return 1;
2258
2259 return 0;
2260}
2261
paul4dadc292005-05-06 21:37:42 +00002262static int
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002263ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +00002264{
2265 int ret = 0;
2266 struct crypt_key *ck;
2267
2268 switch (ntohs (ospfh->auth_type))
2269 {
2270 case OSPF_AUTH_NULL:
2271 ret = 1;
2272 break;
2273 case OSPF_AUTH_SIMPLE:
2274 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2275 ret = 1;
2276 else
2277 ret = 0;
2278 break;
2279 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002280 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002281 {
2282 ret = 0;
2283 break;
2284 }
2285
2286 /* This is very basic, the digest processing is elsewhere */
2287 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2288 ospfh->u.crypt.key_id == ck->key_id &&
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002289 ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE <= OSPF_MAX_PACKET_SIZE)
paul718e3742002-12-13 20:15:29 +00002290 ret = 1;
2291 else
2292 ret = 0;
2293 break;
2294 default:
2295 ret = 0;
2296 break;
2297 }
2298
2299 return ret;
2300}
2301
paul4dadc292005-05-06 21:37:42 +00002302static int
paul718e3742002-12-13 20:15:29 +00002303ospf_check_sum (struct ospf_header *ospfh)
2304{
2305 u_int32_t ret;
2306 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002307
2308 /* clear auth_data for checksum. */
2309 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2310
2311 /* keep checksum and clear. */
2312 sum = ospfh->checksum;
2313 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2314
2315 /* calculate checksum. */
2316 ret = in_cksum (ospfh, ntohs (ospfh->length));
2317
2318 if (ret != sum)
2319 {
2320 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2321 ret, sum);
2322 return 0;
2323 }
2324
2325 return 1;
2326}
2327
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002328/* Verify a complete OSPF packet for proper sizing/alignment. */
2329static unsigned
2330ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2331{
2332 u_int16_t bytesdeclared;
2333
2334 /* Length, 1st approximation. */
2335 if (bytesonwire < OSPF_HEADER_SIZE)
2336 {
2337 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2338 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2339 return MSG_NG;
2340 }
2341 /* Now it is safe to access header fields. Performing length check, allow
2342 * for possible extra bytes of crypto auth/padding, which are not counted
2343 * in the OSPF header "length" field. */
2344 bytesdeclared = ntohs (oh->length);
2345 if (bytesdeclared > bytesonwire)
2346 {
2347 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2348 zlog_debug ("%s: packet length error (%u real, %u declared)",
2349 __func__, bytesonwire, bytesdeclared);
2350 return MSG_NG;
2351 }
2352 /* Length, 2nd approximation. The type-specific constraint is checked
2353 against declared length, not amount of bytes on wire. */
2354 if
2355 (
2356 oh->type >= OSPF_MSG_HELLO &&
2357 oh->type <= OSPF_MSG_LS_ACK &&
2358 bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2359 )
2360 {
2361 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2362 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2363 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2364 return MSG_NG;
2365 }
2366 return MSG_OK;
2367}
2368
paul718e3742002-12-13 20:15:29 +00002369/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002370static int
paul718e3742002-12-13 20:15:29 +00002371ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2372 struct ip *iph, struct ospf_header *ospfh)
2373{
2374 /* check version. */
2375 if (ospfh->version != OSPF_VERSION)
2376 {
2377 zlog_warn ("interface %s: ospf_read version number mismatch.",
2378 IF_NAME (oi));
2379 return -1;
2380 }
2381
Denis Ovsienko71775042011-09-26 13:18:02 +04002382 /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
2383 if (ospfh->type < 1 || ospfh->type > 5)
2384 {
2385 zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
2386 return -1;
2387 }
2388
paul718e3742002-12-13 20:15:29 +00002389 /* Check Area ID. */
2390 if (!ospf_check_area_id (oi, ospfh))
2391 {
2392 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2393 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2394 return -1;
2395 }
2396
2397 /* Check network mask, Silently discarded. */
2398 if (! ospf_check_network_mask (oi, iph->ip_src))
2399 {
2400 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2401 IF_NAME (oi), inet_ntoa (iph->ip_src));
2402 return -1;
2403 }
2404
2405 /* Check authentication. */
2406 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2407 {
paulc6371712006-01-17 17:49:53 +00002408 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2409 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002410 return -1;
2411 }
2412
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002413 if (! ospf_check_auth (oi, ospfh))
paul718e3742002-12-13 20:15:29 +00002414 {
2415 zlog_warn ("interface %s: ospf_read authentication failed.",
2416 IF_NAME (oi));
2417 return -1;
2418 }
2419
2420 /* if check sum is invalid, packet is discarded. */
2421 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2422 {
2423 if (! ospf_check_sum (ospfh))
2424 {
2425 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2426 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2427 return -1;
2428 }
2429 }
2430 else
2431 {
2432 if (ospfh->checksum != 0)
2433 return -1;
2434 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2435 {
2436 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2437 IF_NAME (oi));
2438 return -1;
2439 }
2440 }
2441
2442 return 0;
2443}
2444
2445/* Starting point of packet process function. */
2446int
2447ospf_read (struct thread *thread)
2448{
2449 int ret;
2450 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002451 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002452 struct ospf_interface *oi;
2453 struct ip *iph;
2454 struct ospf_header *ospfh;
2455 u_int16_t length;
2456 struct interface *ifp;
2457
2458 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002459 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002460
2461 /* prepare for next packet. */
2462 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002463
ajs5c333492005-02-23 15:43:01 +00002464 stream_reset(ospf->ibuf);
2465 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002466 return -1;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002467 /* This raw packet is known to be at least as big as its IP header. */
paul718e3742002-12-13 20:15:29 +00002468
ajs5c333492005-02-23 15:43:01 +00002469 /* Note that there should not be alignment problems with this assignment
2470 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002471 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002472 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002473
paulac191232004-10-22 12:05:17 +00002474 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002475 /* Handle cases where the platform does not support retrieving the ifindex,
2476 and also platforms (such as Solaris 8) that claim to support ifindex
2477 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002478 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002479
pauld3f0d622004-05-05 15:27:15 +00002480 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002481 return 0;
paul718e3742002-12-13 20:15:29 +00002482
2483 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002484 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002485 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002486
paul718e3742002-12-13 20:15:29 +00002487 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002488 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002489 {
pauld3241812003-09-29 12:42:39 +00002490 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2491 {
ajs2a42e282004-12-08 18:43:03 +00002492 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002493 inet_ntoa (iph->ip_src));
2494 }
paul718e3742002-12-13 20:15:29 +00002495 return 0;
2496 }
2497
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002498 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2499 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002500 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002501
paul718e3742002-12-13 20:15:29 +00002502 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002503 if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
2504 return -1;
2505 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002506
2507 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002508 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002509
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002510 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2511 after the passive/backbone/other checks below are passed. These checks
2512 in turn access the fields of unverified "ospfh" structure for their own
2513 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002514
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002515 /* If incoming interface is passive one, ignore it. */
2516 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2517 {
2518 char buf[3][INET_ADDRSTRLEN];
2519
2520 if (IS_DEBUG_OSPF_EVENT)
2521 zlog_debug ("ignoring packet from router %s sent to %s, "
2522 "received on a passive interface, %s",
2523 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2524 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2525 inet_ntop(AF_INET, &oi->address->u.prefix4,
2526 buf[2], sizeof(buf[2])));
2527
2528 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2529 {
2530 /* Try to fix multicast membership.
2531 * Some OS:es may have problems in this area,
2532 * make sure it is removed.
2533 */
2534 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2535 ospf_if_set_multicast(oi);
2536 }
2537 return 0;
2538 }
2539
2540
pauld3f0d622004-05-05 15:27:15 +00002541 /* if no local ospf_interface,
2542 * or header area is backbone but ospf_interface is not
2543 * check for VLINK interface
2544 */
2545 if ( (oi == NULL) ||
2546 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2547 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2548 )
2549 {
2550 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2551 {
Paul Jakma88871b12006-06-15 11:41:19 +00002552 if (IS_DEBUG_OSPF_EVENT)
2553 zlog_debug ("Packet from [%s] received on link %s"
2554 " but no ospf_interface",
2555 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002556 return 0;
2557 }
2558 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002559
pauld3f0d622004-05-05 15:27:15 +00002560 /* else it must be a local ospf interface, check it was received on
2561 * correct link
2562 */
2563 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002564 {
Paul Jakma11637432009-08-11 12:25:42 +01002565 if (IS_DEBUG_OSPF_EVENT)
2566 zlog_warn ("Packet from [%s] received on wrong link %s",
2567 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002568 return 0;
2569 }
ajs847947f2005-02-02 18:38:48 +00002570 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002571 {
ajsba6454e2005-02-08 15:37:30 +00002572 char buf[2][INET_ADDRSTRLEN];
2573 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002574 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002575 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2576 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2577 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002578 /* Fix multicast memberships? */
2579 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002580 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002581 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002582 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002583 if (oi->multicast_memberships)
2584 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002585 return 0;
2586 }
paul718e3742002-12-13 20:15:29 +00002587
2588 /*
2589 * If the received packet is destined for AllDRouters, the packet
2590 * should be accepted only if the received ospf interface state is
2591 * either DR or Backup -- endo.
2592 */
2593 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2594 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2595 {
ajsba6454e2005-02-08 15:37:30 +00002596 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002597 inet_ntoa (iph->ip_src), IF_NAME (oi),
2598 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002599 /* Try to fix multicast membership. */
2600 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2601 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002602 return 0;
2603 }
2604
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002605 /* Verify more OSPF header fields. */
2606 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2607 if (ret < 0)
2608 {
2609 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2610 zlog_debug ("ospf_read[%s]: Header check failed, "
2611 "dropping.",
2612 inet_ntoa (iph->ip_src));
2613 return ret;
2614 }
2615
paul718e3742002-12-13 20:15:29 +00002616 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002617 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2618 {
paul718e3742002-12-13 20:15:29 +00002619 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002620 {
ajs2a42e282004-12-08 18:43:03 +00002621 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002622 ospf_packet_dump (ibuf);
2623 }
paul718e3742002-12-13 20:15:29 +00002624
ajs2a42e282004-12-08 18:43:03 +00002625 zlog_debug ("%s received from [%s] via [%s]",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +04002626 LOOKUP (ospf_packet_type_str, ospfh->type),
paul1aa7b392003-04-08 08:51:58 +00002627 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002628 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2629 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002630
2631 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002632 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002633 }
paul718e3742002-12-13 20:15:29 +00002634
paul9985f832005-02-09 15:51:56 +00002635 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002636
2637 /* Adjust size to message length. */
2638 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2639
2640 /* Read rest of the packet and call each sort of packet routine. */
2641 switch (ospfh->type)
2642 {
2643 case OSPF_MSG_HELLO:
2644 ospf_hello (iph, ospfh, ibuf, oi, length);
2645 break;
2646 case OSPF_MSG_DB_DESC:
2647 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2648 break;
2649 case OSPF_MSG_LS_REQ:
2650 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2651 break;
2652 case OSPF_MSG_LS_UPD:
2653 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2654 break;
2655 case OSPF_MSG_LS_ACK:
2656 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2657 break;
2658 default:
2659 zlog (NULL, LOG_WARNING,
2660 "interface %s: OSPF packet header type %d is illegal",
2661 IF_NAME (oi), ospfh->type);
2662 break;
2663 }
2664
paul718e3742002-12-13 20:15:29 +00002665 return 0;
2666}
2667
2668/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002669static void
paul718e3742002-12-13 20:15:29 +00002670ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2671{
2672 struct ospf_header *ospfh;
2673
2674 ospfh = (struct ospf_header *) STREAM_DATA (s);
2675
2676 ospfh->version = (u_char) OSPF_VERSION;
2677 ospfh->type = (u_char) type;
2678
paul68980082003-03-25 05:07:42 +00002679 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002680
2681 ospfh->checksum = 0;
2682 ospfh->area_id = oi->area->area_id;
2683 ospfh->auth_type = htons (ospf_auth_type (oi));
2684
2685 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2686
paul9985f832005-02-09 15:51:56 +00002687 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002688}
2689
2690/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002691static int
paul718e3742002-12-13 20:15:29 +00002692ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2693{
2694 struct crypt_key *ck;
2695
2696 switch (ospf_auth_type (oi))
2697 {
2698 case OSPF_AUTH_NULL:
2699 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2700 break;
2701 case OSPF_AUTH_SIMPLE:
2702 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2703 OSPF_AUTH_SIMPLE_SIZE);
2704 break;
2705 case OSPF_AUTH_CRYPTOGRAPHIC:
2706 /* If key is not set, then set 0. */
2707 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2708 {
2709 ospfh->u.crypt.zero = 0;
2710 ospfh->u.crypt.key_id = 0;
2711 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2712 }
2713 else
2714 {
paul1eb8ef22005-04-07 07:30:20 +00002715 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002716 ospfh->u.crypt.zero = 0;
2717 ospfh->u.crypt.key_id = ck->key_id;
2718 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2719 }
2720 /* note: the seq is done in ospf_make_md5_digest() */
2721 break;
2722 default:
2723 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2724 break;
2725 }
2726
2727 return 0;
2728}
2729
2730/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002731static void
paul718e3742002-12-13 20:15:29 +00002732ospf_fill_header (struct ospf_interface *oi,
2733 struct stream *s, u_int16_t length)
2734{
2735 struct ospf_header *ospfh;
2736
2737 ospfh = (struct ospf_header *) STREAM_DATA (s);
2738
2739 /* Fill length. */
2740 ospfh->length = htons (length);
2741
2742 /* Calculate checksum. */
2743 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2744 ospfh->checksum = in_cksum (ospfh, length);
2745 else
2746 ospfh->checksum = 0;
2747
2748 /* Add Authentication Data. */
2749 ospf_make_auth (oi, ospfh);
2750}
2751
paul4dadc292005-05-06 21:37:42 +00002752static int
paul718e3742002-12-13 20:15:29 +00002753ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2754{
2755 struct ospf_neighbor *nbr;
2756 struct route_node *rn;
2757 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2758 struct in_addr mask;
2759 unsigned long p;
2760 int flag = 0;
2761
2762 /* Set netmask of interface. */
2763 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2764 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2765 masklen2ip (oi->address->prefixlen, &mask);
2766 else
2767 memset ((char *) &mask, 0, sizeof (struct in_addr));
2768 stream_put_ipv4 (s, mask.s_addr);
2769
2770 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002771 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2772 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2773 else
2774 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002775
2776 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002777 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002778 OPTIONS(oi), IF_NAME (oi));
2779
2780 /* Set Options. */
2781 stream_putc (s, OPTIONS (oi));
2782
2783 /* Set Router Priority. */
2784 stream_putc (s, PRIORITY (oi));
2785
2786 /* Set Router Dead Interval. */
2787 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2788
2789 /* Set Designated Router. */
2790 stream_put_ipv4 (s, DR (oi).s_addr);
2791
paul9985f832005-02-09 15:51:56 +00002792 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002793
2794 /* Set Backup Designated Router. */
2795 stream_put_ipv4 (s, BDR (oi).s_addr);
2796
2797 /* Add neighbor seen. */
2798 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002799 if ((nbr = rn->info))
2800 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2801 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2802 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2803 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002804 {
2805 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002806 if (nbr->d_router.s_addr != 0
2807 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2808 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2809 flag = 1;
paul718e3742002-12-13 20:15:29 +00002810
2811 stream_put_ipv4 (s, nbr->router_id.s_addr);
2812 length += 4;
2813 }
2814
2815 /* Let neighbor generate BackupSeen. */
2816 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002817 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002818
2819 return length;
2820}
2821
paul4dadc292005-05-06 21:37:42 +00002822static int
paul718e3742002-12-13 20:15:29 +00002823ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2824 struct stream *s)
2825{
2826 struct ospf_lsa *lsa;
2827 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2828 u_char options;
2829 unsigned long pp;
2830 int i;
2831 struct ospf_lsdb *lsdb;
2832
2833 /* Set Interface MTU. */
2834 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2835 stream_putw (s, 0);
2836 else
2837 stream_putw (s, oi->ifp->mtu);
2838
2839 /* Set Options. */
2840 options = OPTIONS (oi);
2841#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002842 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002843 {
2844 if (IS_SET_DD_I (nbr->dd_flags)
2845 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2846 /*
2847 * Set O-bit in the outgoing DD packet for capablity negotiation,
2848 * if one of following case is applicable.
2849 *
2850 * 1) WaitTimer expiration event triggered the neighbor state to
2851 * change to Exstart, but no (valid) DD packet has received
2852 * from the neighbor yet.
2853 *
2854 * 2) At least one DD packet with O-bit on has received from the
2855 * neighbor.
2856 */
2857 SET_FLAG (options, OSPF_OPTION_O);
2858 }
2859#endif /* HAVE_OPAQUE_LSA */
2860 stream_putc (s, options);
2861
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002862 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002863 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002864 stream_putc (s, nbr->dd_flags);
2865
2866 /* Set DD Sequence Number. */
2867 stream_putl (s, nbr->dd_seqnum);
2868
Paul Jakmab5aeb442006-08-30 18:47:37 +00002869 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002870 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002871 goto empty;
paul718e3742002-12-13 20:15:29 +00002872
2873 /* Describe LSA Header from Database Summary List. */
2874 lsdb = &nbr->db_sum;
2875
2876 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2877 {
2878 struct route_table *table = lsdb->type[i].db;
2879 struct route_node *rn;
2880
2881 for (rn = route_top (table); rn; rn = route_next (rn))
2882 if ((lsa = rn->info) != NULL)
2883 {
2884#ifdef HAVE_OPAQUE_LSA
2885 if (IS_OPAQUE_LSA (lsa->data->type)
2886 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2887 {
2888 /* Suppress advertising opaque-informations. */
2889 /* Remove LSA from DB summary list. */
2890 ospf_lsdb_delete (lsdb, lsa);
2891 continue;
2892 }
2893#endif /* HAVE_OPAQUE_LSA */
2894
2895 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2896 {
2897 struct lsa_header *lsah;
2898 u_int16_t ls_age;
2899
2900 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002901 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002902 break;
2903
2904 /* Keep pointer to LS age. */
2905 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002906 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002907
2908 /* Proceed stream pointer. */
2909 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2910 length += OSPF_LSA_HEADER_SIZE;
2911
2912 /* Set LS age. */
2913 ls_age = LS_AGE (lsa);
2914 lsah->ls_age = htons (ls_age);
2915
2916 }
2917
2918 /* Remove LSA from DB summary list. */
2919 ospf_lsdb_delete (lsdb, lsa);
2920 }
2921 }
2922
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002923 /* Update 'More' bit */
2924 if (ospf_db_summary_isempty (nbr))
2925 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002926empty:
2927 if (nbr->state >= NSM_Exchange)
2928 {
2929 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2930 /* Rewrite DD flags */
2931 stream_putc_at (s, pp, nbr->dd_flags);
2932 }
2933 else
2934 {
2935 assert (IS_SET_DD_M(nbr->dd_flags));
2936 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002937 }
paul718e3742002-12-13 20:15:29 +00002938 return length;
2939}
2940
paul4dadc292005-05-06 21:37:42 +00002941static int
paul718e3742002-12-13 20:15:29 +00002942ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2943 unsigned long delta, struct ospf_neighbor *nbr,
2944 struct ospf_lsa *lsa)
2945{
2946 struct ospf_interface *oi;
2947
2948 oi = nbr->oi;
2949
2950 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002951 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002952 return 0;
2953
2954 stream_putl (s, lsa->data->type);
2955 stream_put_ipv4 (s, lsa->data->id.s_addr);
2956 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2957
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002958 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002959 nbr->ls_req_last = ospf_lsa_lock (lsa);
2960
2961 *length += 12;
2962 return 1;
2963}
2964
paul4dadc292005-05-06 21:37:42 +00002965static int
paul718e3742002-12-13 20:15:29 +00002966ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2967{
2968 struct ospf_lsa *lsa;
2969 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002970 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002971 struct route_table *table;
2972 struct route_node *rn;
2973 int i;
2974 struct ospf_lsdb *lsdb;
2975
2976 lsdb = &nbr->ls_req;
2977
2978 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2979 {
2980 table = lsdb->type[i].db;
2981 for (rn = route_top (table); rn; rn = route_next (rn))
2982 if ((lsa = (rn->info)) != NULL)
2983 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2984 {
2985 route_unlock_node (rn);
2986 break;
2987 }
2988 }
2989 return length;
2990}
2991
paul4dadc292005-05-06 21:37:42 +00002992static int
paul718e3742002-12-13 20:15:29 +00002993ls_age_increment (struct ospf_lsa *lsa, int delay)
2994{
2995 int age;
2996
2997 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2998
2999 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3000}
3001
paul4dadc292005-05-06 21:37:42 +00003002static int
hasso52dc7ee2004-09-23 19:18:23 +00003003ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003004{
3005 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00003006 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003007 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00003008 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00003009 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003010 unsigned long pp;
3011 int count = 0;
3012
3013 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003014 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00003015
paul9985f832005-02-09 15:51:56 +00003016 pp = stream_get_endp (s);
3017 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003018 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00003019
gdt86f1fd92005-01-10 14:20:43 +00003020 /* Calculate amount of packet usable for data. */
3021 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3022
paul718e3742002-12-13 20:15:29 +00003023 while ((node = listhead (update)) != NULL)
3024 {
3025 struct lsa_header *lsah;
3026 u_int16_t ls_age;
3027
3028 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003029 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00003030
paul1eb8ef22005-04-07 07:30:20 +00003031 lsa = listgetdata (node);
3032
paul718e3742002-12-13 20:15:29 +00003033 assert (lsa->data);
3034
paul68b73392004-09-12 14:21:37 +00003035 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00003036 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00003037 break;
3038
paul718e3742002-12-13 20:15:29 +00003039 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00003040 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003041
3042 /* Put LSA to Link State Request. */
3043 stream_put (s, lsa->data, ntohs (lsa->data->length));
3044
3045 /* Set LS age. */
3046 /* each hop must increment an lsa_age by transmit_delay
3047 of OSPF interface */
3048 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3049 lsah->ls_age = htons (ls_age);
3050
3051 length += ntohs (lsa->data->length);
3052 count++;
3053
3054 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003055 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003056 }
3057
3058 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003059 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003060
3061 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003062 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003063 return length;
3064}
3065
paul4dadc292005-05-06 21:37:42 +00003066static int
hasso52dc7ee2004-09-23 19:18:23 +00003067ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003068{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003069 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003070 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003071 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003072 struct ospf_lsa *lsa;
3073
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003074 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003075 {
paul718e3742002-12-13 20:15:29 +00003076 assert (lsa);
3077
gdt86f1fd92005-01-10 14:20:43 +00003078 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003079 break;
3080
3081 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3082 length += OSPF_LSA_HEADER_SIZE;
3083
paul718e3742002-12-13 20:15:29 +00003084 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003085 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003086 }
3087
paul718e3742002-12-13 20:15:29 +00003088 return length;
3089}
3090
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003091static void
3092ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003093{
3094 struct ospf_packet *op;
3095 u_int16_t length = OSPF_HEADER_SIZE;
3096
3097 op = ospf_packet_new (oi->ifp->mtu);
3098
3099 /* Prepare OSPF common header. */
3100 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3101
3102 /* Prepare OSPF Hello body. */
3103 length += ospf_make_hello (oi, op->s);
3104
3105 /* Fill OSPF header. */
3106 ospf_fill_header (oi, op->s, length);
3107
3108 /* Set packet length. */
3109 op->length = length;
3110
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003111 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003112
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003113 /* Add packet to the top of the interface output queue, so that they
3114 * can't get delayed by things like long queues of LS Update packets
3115 */
3116 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003117
3118 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003119 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003120}
3121
paul4dadc292005-05-06 21:37:42 +00003122static void
paul718e3742002-12-13 20:15:29 +00003123ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3124{
3125 struct ospf_interface *oi;
3126
3127 oi = nbr_nbma->oi;
3128 assert(oi);
3129
3130 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003131 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003132 return;
3133
3134 if (oi->type != OSPF_IFTYPE_NBMA)
3135 return;
3136
3137 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3138 return;
3139
3140 if (PRIORITY(oi) == 0)
3141 return;
3142
3143 if (nbr_nbma->priority == 0
3144 && oi->state != ISM_DR && oi->state != ISM_Backup)
3145 return;
3146
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003147 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003148}
3149
3150int
3151ospf_poll_timer (struct thread *thread)
3152{
3153 struct ospf_nbr_nbma *nbr_nbma;
3154
3155 nbr_nbma = THREAD_ARG (thread);
3156 nbr_nbma->t_poll = NULL;
3157
3158 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003159 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003160 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3161
3162 ospf_poll_send (nbr_nbma);
3163
3164 if (nbr_nbma->v_poll > 0)
3165 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3166 nbr_nbma->v_poll);
3167
3168 return 0;
3169}
3170
3171
3172int
3173ospf_hello_reply_timer (struct thread *thread)
3174{
3175 struct ospf_neighbor *nbr;
3176
3177 nbr = THREAD_ARG (thread);
3178 nbr->t_hello_reply = NULL;
3179
3180 assert (nbr->oi);
3181
3182 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003183 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003184 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3185
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003186 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003187
3188 return 0;
3189}
3190
3191/* Send OSPF Hello. */
3192void
3193ospf_hello_send (struct ospf_interface *oi)
3194{
paul718e3742002-12-13 20:15:29 +00003195 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003196 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003197 return;
3198
paul718e3742002-12-13 20:15:29 +00003199 if (oi->type == OSPF_IFTYPE_NBMA)
3200 {
3201 struct ospf_neighbor *nbr;
3202 struct route_node *rn;
3203
3204 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3205 if ((nbr = rn->info))
3206 if (nbr != oi->nbr_self)
3207 if (nbr->state != NSM_Down)
3208 {
3209 /* RFC 2328 Section 9.5.1
3210 If the router is not eligible to become Designated Router,
3211 it must periodically send Hello Packets to both the
3212 Designated Router and the Backup Designated Router (if they
3213 exist). */
3214 if (PRIORITY(oi) == 0 &&
3215 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3216 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3217 continue;
3218
3219 /* If the router is eligible to become Designated Router, it
3220 must periodically send Hello Packets to all neighbors that
3221 are also eligible. In addition, if the router is itself the
3222 Designated Router or Backup Designated Router, it must also
3223 send periodic Hello Packets to all other neighbors. */
3224
3225 if (nbr->priority == 0 && oi->state == ISM_DROther)
3226 continue;
3227 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003228 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003229 }
paul718e3742002-12-13 20:15:29 +00003230 }
3231 else
3232 {
3233 /* Decide destination address. */
3234 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003235 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3236 else
3237 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003238 }
3239}
3240
3241/* Send OSPF Database Description. */
3242void
3243ospf_db_desc_send (struct ospf_neighbor *nbr)
3244{
3245 struct ospf_interface *oi;
3246 struct ospf_packet *op;
3247 u_int16_t length = OSPF_HEADER_SIZE;
3248
3249 oi = nbr->oi;
3250 op = ospf_packet_new (oi->ifp->mtu);
3251
3252 /* Prepare OSPF common header. */
3253 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3254
3255 /* Prepare OSPF Database Description body. */
3256 length += ospf_make_db_desc (oi, nbr, op->s);
3257
3258 /* Fill OSPF header. */
3259 ospf_fill_header (oi, op->s, length);
3260
3261 /* Set packet length. */
3262 op->length = length;
3263
3264 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003265 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3266 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3267 else
3268 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003269
3270 /* Add packet to the interface output queue. */
3271 ospf_packet_add (oi, op);
3272
3273 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003274 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003275
3276 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3277 if (nbr->last_send)
3278 ospf_packet_free (nbr->last_send);
3279 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003280 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003281}
3282
3283/* Re-send Database Description. */
3284void
3285ospf_db_desc_resend (struct ospf_neighbor *nbr)
3286{
3287 struct ospf_interface *oi;
3288
3289 oi = nbr->oi;
3290
3291 /* Add packet to the interface output queue. */
3292 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3293
3294 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003295 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003296}
3297
3298/* Send Link State Request. */
3299void
3300ospf_ls_req_send (struct ospf_neighbor *nbr)
3301{
3302 struct ospf_interface *oi;
3303 struct ospf_packet *op;
3304 u_int16_t length = OSPF_HEADER_SIZE;
3305
3306 oi = nbr->oi;
3307 op = ospf_packet_new (oi->ifp->mtu);
3308
3309 /* Prepare OSPF common header. */
3310 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3311
3312 /* Prepare OSPF Link State Request body. */
3313 length += ospf_make_ls_req (nbr, op->s);
3314 if (length == OSPF_HEADER_SIZE)
3315 {
3316 ospf_packet_free (op);
3317 return;
3318 }
3319
3320 /* Fill OSPF header. */
3321 ospf_fill_header (oi, op->s, length);
3322
3323 /* Set packet length. */
3324 op->length = length;
3325
3326 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003327 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3328 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3329 else
3330 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003331
3332 /* Add packet to the interface output queue. */
3333 ospf_packet_add (oi, op);
3334
3335 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003336 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003337
3338 /* Add Link State Request Retransmission Timer. */
3339 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3340}
3341
3342/* Send Link State Update with an LSA. */
3343void
3344ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3345 int flag)
3346{
hasso52dc7ee2004-09-23 19:18:23 +00003347 struct list *update;
paul718e3742002-12-13 20:15:29 +00003348
3349 update = list_new ();
3350
3351 listnode_add (update, lsa);
3352 ospf_ls_upd_send (nbr, update, flag);
3353
3354 list_delete (update);
3355}
3356
paul68b73392004-09-12 14:21:37 +00003357/* Determine size for packet. Must be at least big enough to accomodate next
3358 * LSA on list, which may be bigger than MTU size.
3359 *
3360 * Return pointer to new ospf_packet
3361 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3362 * on packet sizes (in which case offending LSA is deleted from update list)
3363 */
3364static struct ospf_packet *
3365ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3366{
3367 struct ospf_lsa *lsa;
3368 struct listnode *ln;
3369 size_t size;
3370 static char warned = 0;
3371
paul1eb8ef22005-04-07 07:30:20 +00003372 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003373 assert (lsa->data);
3374
3375 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3376 > ospf_packet_max (oi))
3377 {
3378 if (!warned)
3379 {
3380 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3381 "will need to fragment. Not optimal. Try divide up"
3382 " your network with areas. Use 'debug ospf packet send'"
3383 " to see details, or look at 'show ip ospf database ..'");
3384 warned = 1;
3385 }
3386
3387 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003388 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003389 " %d bytes originated by %s, will be fragmented!",
3390 inet_ntoa (lsa->data->id),
3391 ntohs (lsa->data->length),
3392 inet_ntoa (lsa->data->adv_router));
3393
3394 /*
3395 * Allocate just enough to fit this LSA only, to avoid including other
3396 * LSAs in fragmented LSA Updates.
3397 */
3398 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3399 + OSPF_LS_UPD_MIN_SIZE;
3400 }
3401 else
3402 size = oi->ifp->mtu;
3403
3404 if (size > OSPF_MAX_PACKET_SIZE)
3405 {
3406 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003407 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003408 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003409 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003410 (long int) size);
paul68b73392004-09-12 14:21:37 +00003411 list_delete_node (update, ln);
3412 return NULL;
3413 }
3414
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003415 /* IP header is built up separately by ospf_write(). This means, that we must
3416 * reduce the "affordable" size just calculated by length of an IP header.
3417 * This makes sure, that even if we manage to fill the payload with LSA data
3418 * completely, the final packet (our data plus IP header) still fits into
3419 * outgoing interface MTU. This correction isn't really meaningful for an
3420 * oversized LSA, but for consistency the correction is done for both cases.
3421 *
3422 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3423 */
3424 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003425}
3426
paul718e3742002-12-13 20:15:29 +00003427static void
hasso52dc7ee2004-09-23 19:18:23 +00003428ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003429 struct in_addr addr)
3430{
3431 struct ospf_packet *op;
3432 u_int16_t length = OSPF_HEADER_SIZE;
3433
3434 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003435 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003436
3437 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003438
3439 /* Prepare OSPF common header. */
3440 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3441
paul59ea14c2004-07-14 20:50:36 +00003442 /* Prepare OSPF Link State Update body.
3443 * Includes Type-7 translation.
3444 */
paul718e3742002-12-13 20:15:29 +00003445 length += ospf_make_ls_upd (oi, update, op->s);
3446
3447 /* Fill OSPF header. */
3448 ospf_fill_header (oi, op->s, length);
3449
3450 /* Set packet length. */
3451 op->length = length;
3452
3453 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003454 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3455 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3456 else
3457 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003458
3459 /* Add packet to the interface output queue. */
3460 ospf_packet_add (oi, op);
3461
3462 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003463 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003464}
3465
3466static int
3467ospf_ls_upd_send_queue_event (struct thread *thread)
3468{
3469 struct ospf_interface *oi = THREAD_ARG(thread);
3470 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003471 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003472 struct list *update;
paul68b73392004-09-12 14:21:37 +00003473 char again = 0;
paul718e3742002-12-13 20:15:29 +00003474
3475 oi->t_ls_upd_event = NULL;
3476
3477 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003478 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003479
paul736d3442003-07-24 23:22:57 +00003480 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003481 {
paul736d3442003-07-24 23:22:57 +00003482 rnext = route_next (rn);
3483
paul718e3742002-12-13 20:15:29 +00003484 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003485 continue;
paul68b73392004-09-12 14:21:37 +00003486
3487 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003488
paul48fe13b2004-07-27 17:40:44 +00003489 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003490
paul68b73392004-09-12 14:21:37 +00003491 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003492 if (listcount(update) == 0)
3493 {
3494 list_delete (rn->info);
3495 rn->info = NULL;
3496 route_unlock_node (rn);
3497 }
3498 else
paul68b73392004-09-12 14:21:37 +00003499 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003500 }
3501
3502 if (again != 0)
3503 {
3504 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003505 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003506 " %d nodes to try again, raising new event", again);
3507 oi->t_ls_upd_event =
3508 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003509 }
3510
3511 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003512 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003513
paul718e3742002-12-13 20:15:29 +00003514 return 0;
3515}
3516
3517void
hasso52dc7ee2004-09-23 19:18:23 +00003518ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003519{
3520 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003521 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003522 struct prefix_ipv4 p;
3523 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003524 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003525
3526 oi = nbr->oi;
3527
3528 p.family = AF_INET;
3529 p.prefixlen = IPV4_MAX_BITLEN;
3530
3531 /* Decide destination address. */
3532 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3533 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003534 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3535 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003536 else if (flag == OSPF_SEND_PACKET_DIRECT)
3537 p.prefix = nbr->address.u.prefix4;
3538 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3539 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003540 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3541 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003542 else
3543 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3544
3545 if (oi->type == OSPF_IFTYPE_NBMA)
3546 {
3547 if (flag == OSPF_SEND_PACKET_INDIRECT)
3548 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3549 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3550 zlog_warn ("* LS-Update is sent to myself.");
3551 }
3552
3553 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3554
3555 if (rn->info == NULL)
3556 rn->info = list_new ();
3557
paul1eb8ef22005-04-07 07:30:20 +00003558 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003559 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003560
3561 if (oi->t_ls_upd_event == NULL)
3562 oi->t_ls_upd_event =
3563 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3564}
3565
3566static void
hasso52dc7ee2004-09-23 19:18:23 +00003567ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3568 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003569{
3570 struct ospf_packet *op;
3571 u_int16_t length = OSPF_HEADER_SIZE;
3572
3573 op = ospf_packet_new (oi->ifp->mtu);
3574
3575 /* Prepare OSPF common header. */
3576 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3577
3578 /* Prepare OSPF Link State Acknowledgment body. */
3579 length += ospf_make_ls_ack (oi, ack, op->s);
3580
3581 /* Fill OSPF header. */
3582 ospf_fill_header (oi, op->s, length);
3583
3584 /* Set packet length. */
3585 op->length = length;
3586
3587 /* Set destination IP address. */
3588 op->dst = dst;
3589
3590 /* Add packet to the interface output queue. */
3591 ospf_packet_add (oi, op);
3592
3593 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003594 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003595}
3596
3597static int
3598ospf_ls_ack_send_event (struct thread *thread)
3599{
3600 struct ospf_interface *oi = THREAD_ARG (thread);
3601
3602 oi->t_ls_ack_direct = NULL;
3603
3604 while (listcount (oi->ls_ack_direct.ls_ack))
3605 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3606 oi->ls_ack_direct.dst);
3607
3608 return 0;
3609}
3610
3611void
3612ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3613{
3614 struct ospf_interface *oi = nbr->oi;
3615
3616 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3617 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3618
3619 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3620
3621 if (oi->t_ls_ack_direct == NULL)
3622 oi->t_ls_ack_direct =
3623 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3624}
3625
3626/* Send Link State Acknowledgment delayed. */
3627void
3628ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3629{
3630 struct in_addr dst;
3631
3632 /* Decide destination address. */
3633 /* RFC2328 Section 13.5 On non-broadcast
3634 networks, delayed Link State Acknowledgment packets must be
3635 unicast separately over each adjacency (i.e., neighbor whose
3636 state is >= Exchange). */
3637 if (oi->type == OSPF_IFTYPE_NBMA)
3638 {
3639 struct ospf_neighbor *nbr;
3640 struct route_node *rn;
3641
3642 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3643 if ((nbr = rn->info) != NULL)
3644 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3645 while (listcount (oi->ls_ack))
3646 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3647 return;
3648 }
3649 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3650 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3651 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3652 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3653 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3654 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003655 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3656 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003657 else
3658 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3659
3660 while (listcount (oi->ls_ack))
3661 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3662}