blob: d52430a3e8c433309d62c14544dd7567ef615ef3 [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
paul718e3742002-12-13 20:15:29 +00002263ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2264 struct ospf_header *ospfh)
2265{
2266 int ret = 0;
2267 struct crypt_key *ck;
2268
2269 switch (ntohs (ospfh->auth_type))
2270 {
2271 case OSPF_AUTH_NULL:
2272 ret = 1;
2273 break;
2274 case OSPF_AUTH_SIMPLE:
2275 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2276 ret = 1;
2277 else
2278 ret = 0;
2279 break;
2280 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002281 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002282 {
2283 ret = 0;
2284 break;
2285 }
2286
2287 /* This is very basic, the digest processing is elsewhere */
2288 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2289 ospfh->u.crypt.key_id == ck->key_id &&
2290 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2291 ret = 1;
2292 else
2293 ret = 0;
2294 break;
2295 default:
2296 ret = 0;
2297 break;
2298 }
2299
2300 return ret;
2301}
2302
paul4dadc292005-05-06 21:37:42 +00002303static int
paul718e3742002-12-13 20:15:29 +00002304ospf_check_sum (struct ospf_header *ospfh)
2305{
2306 u_int32_t ret;
2307 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002308
2309 /* clear auth_data for checksum. */
2310 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2311
2312 /* keep checksum and clear. */
2313 sum = ospfh->checksum;
2314 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2315
2316 /* calculate checksum. */
2317 ret = in_cksum (ospfh, ntohs (ospfh->length));
2318
2319 if (ret != sum)
2320 {
2321 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2322 ret, sum);
2323 return 0;
2324 }
2325
2326 return 1;
2327}
2328
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002329/* Verify a complete OSPF packet for proper sizing/alignment. */
2330static unsigned
2331ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2332{
2333 u_int16_t bytesdeclared;
2334
2335 /* Length, 1st approximation. */
2336 if (bytesonwire < OSPF_HEADER_SIZE)
2337 {
2338 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2339 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2340 return MSG_NG;
2341 }
2342 /* Now it is safe to access header fields. Performing length check, allow
2343 * for possible extra bytes of crypto auth/padding, which are not counted
2344 * in the OSPF header "length" field. */
2345 bytesdeclared = ntohs (oh->length);
2346 if (bytesdeclared > bytesonwire)
2347 {
2348 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2349 zlog_debug ("%s: packet length error (%u real, %u declared)",
2350 __func__, bytesonwire, bytesdeclared);
2351 return MSG_NG;
2352 }
2353 /* Length, 2nd approximation. The type-specific constraint is checked
2354 against declared length, not amount of bytes on wire. */
2355 if
2356 (
2357 oh->type >= OSPF_MSG_HELLO &&
2358 oh->type <= OSPF_MSG_LS_ACK &&
2359 bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2360 )
2361 {
2362 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2363 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2364 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2365 return MSG_NG;
2366 }
2367 return MSG_OK;
2368}
2369
paul718e3742002-12-13 20:15:29 +00002370/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002371static int
paul718e3742002-12-13 20:15:29 +00002372ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2373 struct ip *iph, struct ospf_header *ospfh)
2374{
2375 /* check version. */
2376 if (ospfh->version != OSPF_VERSION)
2377 {
2378 zlog_warn ("interface %s: ospf_read version number mismatch.",
2379 IF_NAME (oi));
2380 return -1;
2381 }
2382
Denis Ovsienko71775042011-09-26 13:18:02 +04002383 /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
2384 if (ospfh->type < 1 || ospfh->type > 5)
2385 {
2386 zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
2387 return -1;
2388 }
2389
paul718e3742002-12-13 20:15:29 +00002390 /* Check Area ID. */
2391 if (!ospf_check_area_id (oi, ospfh))
2392 {
2393 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2394 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2395 return -1;
2396 }
2397
2398 /* Check network mask, Silently discarded. */
2399 if (! ospf_check_network_mask (oi, iph->ip_src))
2400 {
2401 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2402 IF_NAME (oi), inet_ntoa (iph->ip_src));
2403 return -1;
2404 }
2405
2406 /* Check authentication. */
2407 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2408 {
paulc6371712006-01-17 17:49:53 +00002409 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2410 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002411 return -1;
2412 }
2413
2414 if (! ospf_check_auth (oi, ibuf, ospfh))
2415 {
2416 zlog_warn ("interface %s: ospf_read authentication failed.",
2417 IF_NAME (oi));
2418 return -1;
2419 }
2420
2421 /* if check sum is invalid, packet is discarded. */
2422 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2423 {
2424 if (! ospf_check_sum (ospfh))
2425 {
2426 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2427 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2428 return -1;
2429 }
2430 }
2431 else
2432 {
2433 if (ospfh->checksum != 0)
2434 return -1;
2435 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2436 {
2437 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2438 IF_NAME (oi));
2439 return -1;
2440 }
2441 }
2442
2443 return 0;
2444}
2445
2446/* Starting point of packet process function. */
2447int
2448ospf_read (struct thread *thread)
2449{
2450 int ret;
2451 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002452 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002453 struct ospf_interface *oi;
2454 struct ip *iph;
2455 struct ospf_header *ospfh;
2456 u_int16_t length;
2457 struct interface *ifp;
2458
2459 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002460 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002461
2462 /* prepare for next packet. */
2463 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002464
ajs5c333492005-02-23 15:43:01 +00002465 stream_reset(ospf->ibuf);
2466 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002467 return -1;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002468 /* This raw packet is known to be at least as big as its IP header. */
paul718e3742002-12-13 20:15:29 +00002469
ajs5c333492005-02-23 15:43:01 +00002470 /* Note that there should not be alignment problems with this assignment
2471 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002472 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002473 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002474
paulac191232004-10-22 12:05:17 +00002475 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002476 /* Handle cases where the platform does not support retrieving the ifindex,
2477 and also platforms (such as Solaris 8) that claim to support ifindex
2478 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002479 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002480
pauld3f0d622004-05-05 15:27:15 +00002481 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002482 return 0;
paul718e3742002-12-13 20:15:29 +00002483
2484 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002485 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002486 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002487
paul718e3742002-12-13 20:15:29 +00002488 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002489 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002490 {
pauld3241812003-09-29 12:42:39 +00002491 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2492 {
ajs2a42e282004-12-08 18:43:03 +00002493 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002494 inet_ntoa (iph->ip_src));
2495 }
paul718e3742002-12-13 20:15:29 +00002496 return 0;
2497 }
2498
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002499 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2500 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002501 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002502
paul718e3742002-12-13 20:15:29 +00002503 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002504 if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
2505 return -1;
2506 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002507
2508 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002509 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002510
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002511 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2512 after the passive/backbone/other checks below are passed. These checks
2513 in turn access the fields of unverified "ospfh" structure for their own
2514 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002515
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002516 /* If incoming interface is passive one, ignore it. */
2517 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2518 {
2519 char buf[3][INET_ADDRSTRLEN];
2520
2521 if (IS_DEBUG_OSPF_EVENT)
2522 zlog_debug ("ignoring packet from router %s sent to %s, "
2523 "received on a passive interface, %s",
2524 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2525 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2526 inet_ntop(AF_INET, &oi->address->u.prefix4,
2527 buf[2], sizeof(buf[2])));
2528
2529 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2530 {
2531 /* Try to fix multicast membership.
2532 * Some OS:es may have problems in this area,
2533 * make sure it is removed.
2534 */
2535 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2536 ospf_if_set_multicast(oi);
2537 }
2538 return 0;
2539 }
2540
2541
pauld3f0d622004-05-05 15:27:15 +00002542 /* if no local ospf_interface,
2543 * or header area is backbone but ospf_interface is not
2544 * check for VLINK interface
2545 */
2546 if ( (oi == NULL) ||
2547 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2548 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2549 )
2550 {
2551 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2552 {
Paul Jakma88871b12006-06-15 11:41:19 +00002553 if (IS_DEBUG_OSPF_EVENT)
2554 zlog_debug ("Packet from [%s] received on link %s"
2555 " but no ospf_interface",
2556 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002557 return 0;
2558 }
2559 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002560
pauld3f0d622004-05-05 15:27:15 +00002561 /* else it must be a local ospf interface, check it was received on
2562 * correct link
2563 */
2564 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002565 {
Paul Jakma11637432009-08-11 12:25:42 +01002566 if (IS_DEBUG_OSPF_EVENT)
2567 zlog_warn ("Packet from [%s] received on wrong link %s",
2568 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002569 return 0;
2570 }
ajs847947f2005-02-02 18:38:48 +00002571 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002572 {
ajsba6454e2005-02-08 15:37:30 +00002573 char buf[2][INET_ADDRSTRLEN];
2574 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002575 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002576 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2577 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2578 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002579 /* Fix multicast memberships? */
2580 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002581 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002582 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002583 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002584 if (oi->multicast_memberships)
2585 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002586 return 0;
2587 }
paul718e3742002-12-13 20:15:29 +00002588
2589 /*
2590 * If the received packet is destined for AllDRouters, the packet
2591 * should be accepted only if the received ospf interface state is
2592 * either DR or Backup -- endo.
2593 */
2594 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2595 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2596 {
ajsba6454e2005-02-08 15:37:30 +00002597 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002598 inet_ntoa (iph->ip_src), IF_NAME (oi),
2599 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002600 /* Try to fix multicast membership. */
2601 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2602 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002603 return 0;
2604 }
2605
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002606 /* Verify more OSPF header fields. */
2607 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2608 if (ret < 0)
2609 {
2610 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2611 zlog_debug ("ospf_read[%s]: Header check failed, "
2612 "dropping.",
2613 inet_ntoa (iph->ip_src));
2614 return ret;
2615 }
2616
paul718e3742002-12-13 20:15:29 +00002617 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002618 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2619 {
paul718e3742002-12-13 20:15:29 +00002620 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002621 {
ajs2a42e282004-12-08 18:43:03 +00002622 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002623 ospf_packet_dump (ibuf);
2624 }
paul718e3742002-12-13 20:15:29 +00002625
ajs2a42e282004-12-08 18:43:03 +00002626 zlog_debug ("%s received from [%s] via [%s]",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +04002627 LOOKUP (ospf_packet_type_str, ospfh->type),
paul1aa7b392003-04-08 08:51:58 +00002628 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002629 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2630 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002631
2632 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002633 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002634 }
paul718e3742002-12-13 20:15:29 +00002635
paul9985f832005-02-09 15:51:56 +00002636 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002637
2638 /* Adjust size to message length. */
2639 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2640
2641 /* Read rest of the packet and call each sort of packet routine. */
2642 switch (ospfh->type)
2643 {
2644 case OSPF_MSG_HELLO:
2645 ospf_hello (iph, ospfh, ibuf, oi, length);
2646 break;
2647 case OSPF_MSG_DB_DESC:
2648 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2649 break;
2650 case OSPF_MSG_LS_REQ:
2651 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2652 break;
2653 case OSPF_MSG_LS_UPD:
2654 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2655 break;
2656 case OSPF_MSG_LS_ACK:
2657 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2658 break;
2659 default:
2660 zlog (NULL, LOG_WARNING,
2661 "interface %s: OSPF packet header type %d is illegal",
2662 IF_NAME (oi), ospfh->type);
2663 break;
2664 }
2665
paul718e3742002-12-13 20:15:29 +00002666 return 0;
2667}
2668
2669/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002670static void
paul718e3742002-12-13 20:15:29 +00002671ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2672{
2673 struct ospf_header *ospfh;
2674
2675 ospfh = (struct ospf_header *) STREAM_DATA (s);
2676
2677 ospfh->version = (u_char) OSPF_VERSION;
2678 ospfh->type = (u_char) type;
2679
paul68980082003-03-25 05:07:42 +00002680 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002681
2682 ospfh->checksum = 0;
2683 ospfh->area_id = oi->area->area_id;
2684 ospfh->auth_type = htons (ospf_auth_type (oi));
2685
2686 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2687
paul9985f832005-02-09 15:51:56 +00002688 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002689}
2690
2691/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002692static int
paul718e3742002-12-13 20:15:29 +00002693ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2694{
2695 struct crypt_key *ck;
2696
2697 switch (ospf_auth_type (oi))
2698 {
2699 case OSPF_AUTH_NULL:
2700 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2701 break;
2702 case OSPF_AUTH_SIMPLE:
2703 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2704 OSPF_AUTH_SIMPLE_SIZE);
2705 break;
2706 case OSPF_AUTH_CRYPTOGRAPHIC:
2707 /* If key is not set, then set 0. */
2708 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2709 {
2710 ospfh->u.crypt.zero = 0;
2711 ospfh->u.crypt.key_id = 0;
2712 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2713 }
2714 else
2715 {
paul1eb8ef22005-04-07 07:30:20 +00002716 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002717 ospfh->u.crypt.zero = 0;
2718 ospfh->u.crypt.key_id = ck->key_id;
2719 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2720 }
2721 /* note: the seq is done in ospf_make_md5_digest() */
2722 break;
2723 default:
2724 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2725 break;
2726 }
2727
2728 return 0;
2729}
2730
2731/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002732static void
paul718e3742002-12-13 20:15:29 +00002733ospf_fill_header (struct ospf_interface *oi,
2734 struct stream *s, u_int16_t length)
2735{
2736 struct ospf_header *ospfh;
2737
2738 ospfh = (struct ospf_header *) STREAM_DATA (s);
2739
2740 /* Fill length. */
2741 ospfh->length = htons (length);
2742
2743 /* Calculate checksum. */
2744 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2745 ospfh->checksum = in_cksum (ospfh, length);
2746 else
2747 ospfh->checksum = 0;
2748
2749 /* Add Authentication Data. */
2750 ospf_make_auth (oi, ospfh);
2751}
2752
paul4dadc292005-05-06 21:37:42 +00002753static int
paul718e3742002-12-13 20:15:29 +00002754ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2755{
2756 struct ospf_neighbor *nbr;
2757 struct route_node *rn;
2758 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2759 struct in_addr mask;
2760 unsigned long p;
2761 int flag = 0;
2762
2763 /* Set netmask of interface. */
2764 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2765 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2766 masklen2ip (oi->address->prefixlen, &mask);
2767 else
2768 memset ((char *) &mask, 0, sizeof (struct in_addr));
2769 stream_put_ipv4 (s, mask.s_addr);
2770
2771 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002772 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2773 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2774 else
2775 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002776
2777 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002778 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002779 OPTIONS(oi), IF_NAME (oi));
2780
2781 /* Set Options. */
2782 stream_putc (s, OPTIONS (oi));
2783
2784 /* Set Router Priority. */
2785 stream_putc (s, PRIORITY (oi));
2786
2787 /* Set Router Dead Interval. */
2788 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2789
2790 /* Set Designated Router. */
2791 stream_put_ipv4 (s, DR (oi).s_addr);
2792
paul9985f832005-02-09 15:51:56 +00002793 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002794
2795 /* Set Backup Designated Router. */
2796 stream_put_ipv4 (s, BDR (oi).s_addr);
2797
2798 /* Add neighbor seen. */
2799 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002800 if ((nbr = rn->info))
2801 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2802 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2803 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2804 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002805 {
2806 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002807 if (nbr->d_router.s_addr != 0
2808 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2809 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2810 flag = 1;
paul718e3742002-12-13 20:15:29 +00002811
2812 stream_put_ipv4 (s, nbr->router_id.s_addr);
2813 length += 4;
2814 }
2815
2816 /* Let neighbor generate BackupSeen. */
2817 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002818 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002819
2820 return length;
2821}
2822
paul4dadc292005-05-06 21:37:42 +00002823static int
paul718e3742002-12-13 20:15:29 +00002824ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2825 struct stream *s)
2826{
2827 struct ospf_lsa *lsa;
2828 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2829 u_char options;
2830 unsigned long pp;
2831 int i;
2832 struct ospf_lsdb *lsdb;
2833
2834 /* Set Interface MTU. */
2835 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2836 stream_putw (s, 0);
2837 else
2838 stream_putw (s, oi->ifp->mtu);
2839
2840 /* Set Options. */
2841 options = OPTIONS (oi);
2842#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002843 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002844 {
2845 if (IS_SET_DD_I (nbr->dd_flags)
2846 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2847 /*
2848 * Set O-bit in the outgoing DD packet for capablity negotiation,
2849 * if one of following case is applicable.
2850 *
2851 * 1) WaitTimer expiration event triggered the neighbor state to
2852 * change to Exstart, but no (valid) DD packet has received
2853 * from the neighbor yet.
2854 *
2855 * 2) At least one DD packet with O-bit on has received from the
2856 * neighbor.
2857 */
2858 SET_FLAG (options, OSPF_OPTION_O);
2859 }
2860#endif /* HAVE_OPAQUE_LSA */
2861 stream_putc (s, options);
2862
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002863 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002864 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002865 stream_putc (s, nbr->dd_flags);
2866
2867 /* Set DD Sequence Number. */
2868 stream_putl (s, nbr->dd_seqnum);
2869
Paul Jakmab5aeb442006-08-30 18:47:37 +00002870 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002871 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002872 goto empty;
paul718e3742002-12-13 20:15:29 +00002873
2874 /* Describe LSA Header from Database Summary List. */
2875 lsdb = &nbr->db_sum;
2876
2877 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2878 {
2879 struct route_table *table = lsdb->type[i].db;
2880 struct route_node *rn;
2881
2882 for (rn = route_top (table); rn; rn = route_next (rn))
2883 if ((lsa = rn->info) != NULL)
2884 {
2885#ifdef HAVE_OPAQUE_LSA
2886 if (IS_OPAQUE_LSA (lsa->data->type)
2887 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2888 {
2889 /* Suppress advertising opaque-informations. */
2890 /* Remove LSA from DB summary list. */
2891 ospf_lsdb_delete (lsdb, lsa);
2892 continue;
2893 }
2894#endif /* HAVE_OPAQUE_LSA */
2895
2896 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2897 {
2898 struct lsa_header *lsah;
2899 u_int16_t ls_age;
2900
2901 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002902 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002903 break;
2904
2905 /* Keep pointer to LS age. */
2906 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002907 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002908
2909 /* Proceed stream pointer. */
2910 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2911 length += OSPF_LSA_HEADER_SIZE;
2912
2913 /* Set LS age. */
2914 ls_age = LS_AGE (lsa);
2915 lsah->ls_age = htons (ls_age);
2916
2917 }
2918
2919 /* Remove LSA from DB summary list. */
2920 ospf_lsdb_delete (lsdb, lsa);
2921 }
2922 }
2923
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002924 /* Update 'More' bit */
2925 if (ospf_db_summary_isempty (nbr))
2926 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002927empty:
2928 if (nbr->state >= NSM_Exchange)
2929 {
2930 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2931 /* Rewrite DD flags */
2932 stream_putc_at (s, pp, nbr->dd_flags);
2933 }
2934 else
2935 {
2936 assert (IS_SET_DD_M(nbr->dd_flags));
2937 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002938 }
paul718e3742002-12-13 20:15:29 +00002939 return length;
2940}
2941
paul4dadc292005-05-06 21:37:42 +00002942static int
paul718e3742002-12-13 20:15:29 +00002943ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2944 unsigned long delta, struct ospf_neighbor *nbr,
2945 struct ospf_lsa *lsa)
2946{
2947 struct ospf_interface *oi;
2948
2949 oi = nbr->oi;
2950
2951 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002952 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002953 return 0;
2954
2955 stream_putl (s, lsa->data->type);
2956 stream_put_ipv4 (s, lsa->data->id.s_addr);
2957 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2958
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002959 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002960 nbr->ls_req_last = ospf_lsa_lock (lsa);
2961
2962 *length += 12;
2963 return 1;
2964}
2965
paul4dadc292005-05-06 21:37:42 +00002966static int
paul718e3742002-12-13 20:15:29 +00002967ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2968{
2969 struct ospf_lsa *lsa;
2970 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002971 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002972 struct route_table *table;
2973 struct route_node *rn;
2974 int i;
2975 struct ospf_lsdb *lsdb;
2976
2977 lsdb = &nbr->ls_req;
2978
2979 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2980 {
2981 table = lsdb->type[i].db;
2982 for (rn = route_top (table); rn; rn = route_next (rn))
2983 if ((lsa = (rn->info)) != NULL)
2984 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2985 {
2986 route_unlock_node (rn);
2987 break;
2988 }
2989 }
2990 return length;
2991}
2992
paul4dadc292005-05-06 21:37:42 +00002993static int
paul718e3742002-12-13 20:15:29 +00002994ls_age_increment (struct ospf_lsa *lsa, int delay)
2995{
2996 int age;
2997
2998 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2999
3000 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3001}
3002
paul4dadc292005-05-06 21:37:42 +00003003static int
hasso52dc7ee2004-09-23 19:18:23 +00003004ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003005{
3006 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00003007 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003008 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00003009 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00003010 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003011 unsigned long pp;
3012 int count = 0;
3013
3014 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003015 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00003016
paul9985f832005-02-09 15:51:56 +00003017 pp = stream_get_endp (s);
3018 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003019 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00003020
gdt86f1fd92005-01-10 14:20:43 +00003021 /* Calculate amount of packet usable for data. */
3022 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3023
paul718e3742002-12-13 20:15:29 +00003024 while ((node = listhead (update)) != NULL)
3025 {
3026 struct lsa_header *lsah;
3027 u_int16_t ls_age;
3028
3029 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003030 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00003031
paul1eb8ef22005-04-07 07:30:20 +00003032 lsa = listgetdata (node);
3033
paul718e3742002-12-13 20:15:29 +00003034 assert (lsa->data);
3035
paul68b73392004-09-12 14:21:37 +00003036 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00003037 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00003038 break;
3039
paul718e3742002-12-13 20:15:29 +00003040 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00003041 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003042
3043 /* Put LSA to Link State Request. */
3044 stream_put (s, lsa->data, ntohs (lsa->data->length));
3045
3046 /* Set LS age. */
3047 /* each hop must increment an lsa_age by transmit_delay
3048 of OSPF interface */
3049 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3050 lsah->ls_age = htons (ls_age);
3051
3052 length += ntohs (lsa->data->length);
3053 count++;
3054
3055 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003056 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003057 }
3058
3059 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003060 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003061
3062 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003063 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003064 return length;
3065}
3066
paul4dadc292005-05-06 21:37:42 +00003067static int
hasso52dc7ee2004-09-23 19:18:23 +00003068ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003069{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003070 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003071 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003072 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003073 struct ospf_lsa *lsa;
3074
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003075 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003076 {
paul718e3742002-12-13 20:15:29 +00003077 assert (lsa);
3078
gdt86f1fd92005-01-10 14:20:43 +00003079 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003080 break;
3081
3082 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3083 length += OSPF_LSA_HEADER_SIZE;
3084
paul718e3742002-12-13 20:15:29 +00003085 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003086 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003087 }
3088
paul718e3742002-12-13 20:15:29 +00003089 return length;
3090}
3091
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003092static void
3093ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003094{
3095 struct ospf_packet *op;
3096 u_int16_t length = OSPF_HEADER_SIZE;
3097
3098 op = ospf_packet_new (oi->ifp->mtu);
3099
3100 /* Prepare OSPF common header. */
3101 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3102
3103 /* Prepare OSPF Hello body. */
3104 length += ospf_make_hello (oi, op->s);
3105
3106 /* Fill OSPF header. */
3107 ospf_fill_header (oi, op->s, length);
3108
3109 /* Set packet length. */
3110 op->length = length;
3111
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003112 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003113
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003114 /* Add packet to the top of the interface output queue, so that they
3115 * can't get delayed by things like long queues of LS Update packets
3116 */
3117 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003118
3119 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003120 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003121}
3122
paul4dadc292005-05-06 21:37:42 +00003123static void
paul718e3742002-12-13 20:15:29 +00003124ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3125{
3126 struct ospf_interface *oi;
3127
3128 oi = nbr_nbma->oi;
3129 assert(oi);
3130
3131 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003132 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003133 return;
3134
3135 if (oi->type != OSPF_IFTYPE_NBMA)
3136 return;
3137
3138 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3139 return;
3140
3141 if (PRIORITY(oi) == 0)
3142 return;
3143
3144 if (nbr_nbma->priority == 0
3145 && oi->state != ISM_DR && oi->state != ISM_Backup)
3146 return;
3147
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003148 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003149}
3150
3151int
3152ospf_poll_timer (struct thread *thread)
3153{
3154 struct ospf_nbr_nbma *nbr_nbma;
3155
3156 nbr_nbma = THREAD_ARG (thread);
3157 nbr_nbma->t_poll = NULL;
3158
3159 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003160 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003161 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3162
3163 ospf_poll_send (nbr_nbma);
3164
3165 if (nbr_nbma->v_poll > 0)
3166 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3167 nbr_nbma->v_poll);
3168
3169 return 0;
3170}
3171
3172
3173int
3174ospf_hello_reply_timer (struct thread *thread)
3175{
3176 struct ospf_neighbor *nbr;
3177
3178 nbr = THREAD_ARG (thread);
3179 nbr->t_hello_reply = NULL;
3180
3181 assert (nbr->oi);
3182
3183 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003184 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003185 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3186
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003187 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003188
3189 return 0;
3190}
3191
3192/* Send OSPF Hello. */
3193void
3194ospf_hello_send (struct ospf_interface *oi)
3195{
paul718e3742002-12-13 20:15:29 +00003196 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003197 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003198 return;
3199
paul718e3742002-12-13 20:15:29 +00003200 if (oi->type == OSPF_IFTYPE_NBMA)
3201 {
3202 struct ospf_neighbor *nbr;
3203 struct route_node *rn;
3204
3205 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3206 if ((nbr = rn->info))
3207 if (nbr != oi->nbr_self)
3208 if (nbr->state != NSM_Down)
3209 {
3210 /* RFC 2328 Section 9.5.1
3211 If the router is not eligible to become Designated Router,
3212 it must periodically send Hello Packets to both the
3213 Designated Router and the Backup Designated Router (if they
3214 exist). */
3215 if (PRIORITY(oi) == 0 &&
3216 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3217 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3218 continue;
3219
3220 /* If the router is eligible to become Designated Router, it
3221 must periodically send Hello Packets to all neighbors that
3222 are also eligible. In addition, if the router is itself the
3223 Designated Router or Backup Designated Router, it must also
3224 send periodic Hello Packets to all other neighbors. */
3225
3226 if (nbr->priority == 0 && oi->state == ISM_DROther)
3227 continue;
3228 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003229 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003230 }
paul718e3742002-12-13 20:15:29 +00003231 }
3232 else
3233 {
3234 /* Decide destination address. */
3235 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003236 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3237 else
3238 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003239 }
3240}
3241
3242/* Send OSPF Database Description. */
3243void
3244ospf_db_desc_send (struct ospf_neighbor *nbr)
3245{
3246 struct ospf_interface *oi;
3247 struct ospf_packet *op;
3248 u_int16_t length = OSPF_HEADER_SIZE;
3249
3250 oi = nbr->oi;
3251 op = ospf_packet_new (oi->ifp->mtu);
3252
3253 /* Prepare OSPF common header. */
3254 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3255
3256 /* Prepare OSPF Database Description body. */
3257 length += ospf_make_db_desc (oi, nbr, op->s);
3258
3259 /* Fill OSPF header. */
3260 ospf_fill_header (oi, op->s, length);
3261
3262 /* Set packet length. */
3263 op->length = length;
3264
3265 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003266 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3267 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3268 else
3269 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003270
3271 /* Add packet to the interface output queue. */
3272 ospf_packet_add (oi, op);
3273
3274 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003275 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003276
3277 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3278 if (nbr->last_send)
3279 ospf_packet_free (nbr->last_send);
3280 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003281 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003282}
3283
3284/* Re-send Database Description. */
3285void
3286ospf_db_desc_resend (struct ospf_neighbor *nbr)
3287{
3288 struct ospf_interface *oi;
3289
3290 oi = nbr->oi;
3291
3292 /* Add packet to the interface output queue. */
3293 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3294
3295 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003296 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003297}
3298
3299/* Send Link State Request. */
3300void
3301ospf_ls_req_send (struct ospf_neighbor *nbr)
3302{
3303 struct ospf_interface *oi;
3304 struct ospf_packet *op;
3305 u_int16_t length = OSPF_HEADER_SIZE;
3306
3307 oi = nbr->oi;
3308 op = ospf_packet_new (oi->ifp->mtu);
3309
3310 /* Prepare OSPF common header. */
3311 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3312
3313 /* Prepare OSPF Link State Request body. */
3314 length += ospf_make_ls_req (nbr, op->s);
3315 if (length == OSPF_HEADER_SIZE)
3316 {
3317 ospf_packet_free (op);
3318 return;
3319 }
3320
3321 /* Fill OSPF header. */
3322 ospf_fill_header (oi, op->s, length);
3323
3324 /* Set packet length. */
3325 op->length = length;
3326
3327 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003328 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3329 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3330 else
3331 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003332
3333 /* Add packet to the interface output queue. */
3334 ospf_packet_add (oi, op);
3335
3336 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003337 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003338
3339 /* Add Link State Request Retransmission Timer. */
3340 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3341}
3342
3343/* Send Link State Update with an LSA. */
3344void
3345ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3346 int flag)
3347{
hasso52dc7ee2004-09-23 19:18:23 +00003348 struct list *update;
paul718e3742002-12-13 20:15:29 +00003349
3350 update = list_new ();
3351
3352 listnode_add (update, lsa);
3353 ospf_ls_upd_send (nbr, update, flag);
3354
3355 list_delete (update);
3356}
3357
paul68b73392004-09-12 14:21:37 +00003358/* Determine size for packet. Must be at least big enough to accomodate next
3359 * LSA on list, which may be bigger than MTU size.
3360 *
3361 * Return pointer to new ospf_packet
3362 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3363 * on packet sizes (in which case offending LSA is deleted from update list)
3364 */
3365static struct ospf_packet *
3366ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3367{
3368 struct ospf_lsa *lsa;
3369 struct listnode *ln;
3370 size_t size;
3371 static char warned = 0;
3372
paul1eb8ef22005-04-07 07:30:20 +00003373 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003374 assert (lsa->data);
3375
3376 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3377 > ospf_packet_max (oi))
3378 {
3379 if (!warned)
3380 {
3381 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3382 "will need to fragment. Not optimal. Try divide up"
3383 " your network with areas. Use 'debug ospf packet send'"
3384 " to see details, or look at 'show ip ospf database ..'");
3385 warned = 1;
3386 }
3387
3388 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003389 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003390 " %d bytes originated by %s, will be fragmented!",
3391 inet_ntoa (lsa->data->id),
3392 ntohs (lsa->data->length),
3393 inet_ntoa (lsa->data->adv_router));
3394
3395 /*
3396 * Allocate just enough to fit this LSA only, to avoid including other
3397 * LSAs in fragmented LSA Updates.
3398 */
3399 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3400 + OSPF_LS_UPD_MIN_SIZE;
3401 }
3402 else
3403 size = oi->ifp->mtu;
3404
3405 if (size > OSPF_MAX_PACKET_SIZE)
3406 {
3407 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003408 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003409 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003410 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003411 (long int) size);
paul68b73392004-09-12 14:21:37 +00003412 list_delete_node (update, ln);
3413 return NULL;
3414 }
3415
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003416 /* IP header is built up separately by ospf_write(). This means, that we must
3417 * reduce the "affordable" size just calculated by length of an IP header.
3418 * This makes sure, that even if we manage to fill the payload with LSA data
3419 * completely, the final packet (our data plus IP header) still fits into
3420 * outgoing interface MTU. This correction isn't really meaningful for an
3421 * oversized LSA, but for consistency the correction is done for both cases.
3422 *
3423 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3424 */
3425 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003426}
3427
paul718e3742002-12-13 20:15:29 +00003428static void
hasso52dc7ee2004-09-23 19:18:23 +00003429ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003430 struct in_addr addr)
3431{
3432 struct ospf_packet *op;
3433 u_int16_t length = OSPF_HEADER_SIZE;
3434
3435 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003436 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003437
3438 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003439
3440 /* Prepare OSPF common header. */
3441 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3442
paul59ea14c2004-07-14 20:50:36 +00003443 /* Prepare OSPF Link State Update body.
3444 * Includes Type-7 translation.
3445 */
paul718e3742002-12-13 20:15:29 +00003446 length += ospf_make_ls_upd (oi, update, op->s);
3447
3448 /* Fill OSPF header. */
3449 ospf_fill_header (oi, op->s, length);
3450
3451 /* Set packet length. */
3452 op->length = length;
3453
3454 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003455 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3456 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3457 else
3458 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003459
3460 /* Add packet to the interface output queue. */
3461 ospf_packet_add (oi, op);
3462
3463 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003464 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003465}
3466
3467static int
3468ospf_ls_upd_send_queue_event (struct thread *thread)
3469{
3470 struct ospf_interface *oi = THREAD_ARG(thread);
3471 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003472 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003473 struct list *update;
paul68b73392004-09-12 14:21:37 +00003474 char again = 0;
paul718e3742002-12-13 20:15:29 +00003475
3476 oi->t_ls_upd_event = NULL;
3477
3478 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003479 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003480
paul736d3442003-07-24 23:22:57 +00003481 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003482 {
paul736d3442003-07-24 23:22:57 +00003483 rnext = route_next (rn);
3484
paul718e3742002-12-13 20:15:29 +00003485 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003486 continue;
paul68b73392004-09-12 14:21:37 +00003487
3488 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003489
paul48fe13b2004-07-27 17:40:44 +00003490 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003491
paul68b73392004-09-12 14:21:37 +00003492 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003493 if (listcount(update) == 0)
3494 {
3495 list_delete (rn->info);
3496 rn->info = NULL;
3497 route_unlock_node (rn);
3498 }
3499 else
paul68b73392004-09-12 14:21:37 +00003500 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003501 }
3502
3503 if (again != 0)
3504 {
3505 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003506 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003507 " %d nodes to try again, raising new event", again);
3508 oi->t_ls_upd_event =
3509 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003510 }
3511
3512 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003513 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003514
paul718e3742002-12-13 20:15:29 +00003515 return 0;
3516}
3517
3518void
hasso52dc7ee2004-09-23 19:18:23 +00003519ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003520{
3521 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003522 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003523 struct prefix_ipv4 p;
3524 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003525 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003526
3527 oi = nbr->oi;
3528
3529 p.family = AF_INET;
3530 p.prefixlen = IPV4_MAX_BITLEN;
3531
3532 /* Decide destination address. */
3533 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3534 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003535 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3536 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003537 else if (flag == OSPF_SEND_PACKET_DIRECT)
3538 p.prefix = nbr->address.u.prefix4;
3539 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3540 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003541 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3542 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003543 else
3544 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3545
3546 if (oi->type == OSPF_IFTYPE_NBMA)
3547 {
3548 if (flag == OSPF_SEND_PACKET_INDIRECT)
3549 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3550 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3551 zlog_warn ("* LS-Update is sent to myself.");
3552 }
3553
3554 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3555
3556 if (rn->info == NULL)
3557 rn->info = list_new ();
3558
paul1eb8ef22005-04-07 07:30:20 +00003559 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003560 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003561
3562 if (oi->t_ls_upd_event == NULL)
3563 oi->t_ls_upd_event =
3564 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3565}
3566
3567static void
hasso52dc7ee2004-09-23 19:18:23 +00003568ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3569 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003570{
3571 struct ospf_packet *op;
3572 u_int16_t length = OSPF_HEADER_SIZE;
3573
3574 op = ospf_packet_new (oi->ifp->mtu);
3575
3576 /* Prepare OSPF common header. */
3577 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3578
3579 /* Prepare OSPF Link State Acknowledgment body. */
3580 length += ospf_make_ls_ack (oi, ack, op->s);
3581
3582 /* Fill OSPF header. */
3583 ospf_fill_header (oi, op->s, length);
3584
3585 /* Set packet length. */
3586 op->length = length;
3587
3588 /* Set destination IP address. */
3589 op->dst = dst;
3590
3591 /* Add packet to the interface output queue. */
3592 ospf_packet_add (oi, op);
3593
3594 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003595 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003596}
3597
3598static int
3599ospf_ls_ack_send_event (struct thread *thread)
3600{
3601 struct ospf_interface *oi = THREAD_ARG (thread);
3602
3603 oi->t_ls_ack_direct = NULL;
3604
3605 while (listcount (oi->ls_ack_direct.ls_ack))
3606 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3607 oi->ls_ack_direct.dst);
3608
3609 return 0;
3610}
3611
3612void
3613ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3614{
3615 struct ospf_interface *oi = nbr->oi;
3616
3617 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3618 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3619
3620 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3621
3622 if (oi->t_ls_ack_direct == NULL)
3623 oi->t_ls_ack_direct =
3624 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3625}
3626
3627/* Send Link State Acknowledgment delayed. */
3628void
3629ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3630{
3631 struct in_addr dst;
3632
3633 /* Decide destination address. */
3634 /* RFC2328 Section 13.5 On non-broadcast
3635 networks, delayed Link State Acknowledgment packets must be
3636 unicast separately over each adjacency (i.e., neighbor whose
3637 state is >= Exchange). */
3638 if (oi->type == OSPF_IFTYPE_NBMA)
3639 {
3640 struct ospf_neighbor *nbr;
3641 struct route_node *rn;
3642
3643 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3644 if ((nbr = rn->info) != NULL)
3645 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3646 while (listcount (oi->ls_ack))
3647 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3648 return;
3649 }
3650 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3651 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3652 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3653 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3654 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3655 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003656 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3657 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003658 else
3659 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3660
3661 while (listcount (oi->ls_ack))
3662 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3663}