blob: 876320ee8cb45b4d0631f13c177aca09c4b141dc [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
paul718e3742002-12-13 20:15:29 +000064/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000065static int
paul718e3742002-12-13 20:15:29 +000066ospf_auth_type (struct ospf_interface *oi)
67{
68 int auth_type;
69
70 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
71 auth_type = oi->area->auth_type;
72 else
73 auth_type = OSPF_IF_PARAM (oi, auth_type);
74
75 /* Handle case where MD5 key list is not configured aka Cisco */
76 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
77 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
78 return OSPF_AUTH_NULL;
79
80 return auth_type;
81
82}
83
paul718e3742002-12-13 20:15:29 +000084struct ospf_packet *
85ospf_packet_new (size_t size)
86{
87 struct ospf_packet *new;
88
89 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
90 new->s = stream_new (size);
91
92 return new;
93}
94
95void
96ospf_packet_free (struct ospf_packet *op)
97{
98 if (op->s)
99 stream_free (op->s);
100
101 XFREE (MTYPE_OSPF_PACKET, op);
102
103 op = NULL;
104}
105
106struct ospf_fifo *
107ospf_fifo_new ()
108{
109 struct ospf_fifo *new;
110
111 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
112 return new;
113}
114
115/* Add new packet to fifo. */
116void
117ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
118{
119 if (fifo->tail)
120 fifo->tail->next = op;
121 else
122 fifo->head = op;
123
124 fifo->tail = op;
125
126 fifo->count++;
127}
128
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000129/* Add new packet to head of fifo. */
130static void
131ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
132{
133 op->next = fifo->head;
134
135 if (fifo->tail == NULL)
136 fifo->tail = op;
137
138 fifo->head = op;
139
140 fifo->count++;
141}
142
paul718e3742002-12-13 20:15:29 +0000143/* Delete first packet from fifo. */
144struct ospf_packet *
145ospf_fifo_pop (struct ospf_fifo *fifo)
146{
147 struct ospf_packet *op;
148
149 op = fifo->head;
150
151 if (op)
152 {
153 fifo->head = op->next;
154
155 if (fifo->head == NULL)
156 fifo->tail = NULL;
157
158 fifo->count--;
159 }
160
161 return op;
162}
163
164/* Return first fifo entry. */
165struct ospf_packet *
166ospf_fifo_head (struct ospf_fifo *fifo)
167{
168 return fifo->head;
169}
170
171/* Flush ospf packet fifo. */
172void
173ospf_fifo_flush (struct ospf_fifo *fifo)
174{
175 struct ospf_packet *op;
176 struct ospf_packet *next;
177
178 for (op = fifo->head; op; op = next)
179 {
180 next = op->next;
181 ospf_packet_free (op);
182 }
183 fifo->head = fifo->tail = NULL;
184 fifo->count = 0;
185}
186
187/* Free ospf packet fifo. */
188void
189ospf_fifo_free (struct ospf_fifo *fifo)
190{
191 ospf_fifo_flush (fifo);
192
193 XFREE (MTYPE_OSPF_FIFO, fifo);
194}
195
196void
197ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
198{
ajsc3eab872005-01-29 15:52:07 +0000199 if (!oi->obuf)
200 {
201 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
202 "destination %s) called with NULL obuf, ignoring "
203 "(please report this bug)!\n",
204 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400205 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
ajsc3eab872005-01-29 15:52:07 +0000206 inet_ntoa (op->dst));
207 return;
208 }
209
paul718e3742002-12-13 20:15:29 +0000210 /* Add packet to end of queue. */
211 ospf_fifo_push (oi->obuf, op);
212
213 /* Debug of packet fifo*/
214 /* ospf_fifo_debug (oi->obuf); */
215}
216
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000217static void
218ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
219{
220 if (!oi->obuf)
221 {
222 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
223 "destination %s) called with NULL obuf, ignoring "
224 "(please report this bug)!\n",
225 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko7e0e2cb2012-01-20 22:32:10 +0400226 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000227 inet_ntoa (op->dst));
228 return;
229 }
230
231 /* Add packet to head of queue. */
232 ospf_fifo_push_head (oi->obuf, op);
233
234 /* Debug of packet fifo*/
235 /* ospf_fifo_debug (oi->obuf); */
236}
237
paul718e3742002-12-13 20:15:29 +0000238void
239ospf_packet_delete (struct ospf_interface *oi)
240{
241 struct ospf_packet *op;
242
243 op = ospf_fifo_pop (oi->obuf);
244
245 if (op)
246 ospf_packet_free (op);
247}
248
paul718e3742002-12-13 20:15:29 +0000249struct ospf_packet *
250ospf_packet_dup (struct ospf_packet *op)
251{
252 struct ospf_packet *new;
253
paul37163d62003-02-03 18:40:56 +0000254 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000255 /* XXX size_t */
256 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
257 (u_long)STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000258
259 /* Reserve space for MD5 authentication that may be added later. */
260 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000261 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000262
263 new->dst = op->dst;
264 new->length = op->length;
265
266 return new;
267}
268
gdt86f1fd92005-01-10 14:20:43 +0000269/* XXX inline */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100270static unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000271ospf_packet_authspace (struct ospf_interface *oi)
272{
273 int auth = 0;
274
275 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
276 auth = OSPF_AUTH_MD5_SIZE;
277
278 return auth;
279}
280
paul4dadc292005-05-06 21:37:42 +0000281static unsigned int
paul718e3742002-12-13 20:15:29 +0000282ospf_packet_max (struct ospf_interface *oi)
283{
284 int max;
285
gdt86f1fd92005-01-10 14:20:43 +0000286 max = oi->ifp->mtu - ospf_packet_authspace(oi);
287
paul68b73392004-09-12 14:21:37 +0000288 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000289
290 return max;
291}
292
293
paul4dadc292005-05-06 21:37:42 +0000294static int
paul718e3742002-12-13 20:15:29 +0000295ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
296 u_int16_t length)
297{
paul6c835672004-10-11 11:00:30 +0000298 unsigned char *ibuf;
vincentc1a03d42005-09-28 15:47:44 +0000299 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000300 unsigned char digest[OSPF_AUTH_MD5_SIZE];
301 unsigned char *pdigest;
302 struct crypt_key *ck;
303 struct ospf_header *ospfh;
304 struct ospf_neighbor *nbr;
305
306
307 ibuf = STREAM_PNT (s);
308 ospfh = (struct ospf_header *) ibuf;
309
310 /* Get pointer to the end of the packet. */
311 pdigest = ibuf + length;
312
313 /* Get secret key. */
314 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
315 ospfh->u.crypt.key_id);
316 if (ck == NULL)
317 {
318 zlog_warn ("interface %s: ospf_check_md5 no key %d",
319 IF_NAME (oi), ospfh->u.crypt.key_id);
320 return 0;
321 }
322
323 /* check crypto seqnum. */
324 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
325
326 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
327 {
328 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
329 IF_NAME (oi),
330 ntohl(ospfh->u.crypt.crypt_seqnum),
331 ntohl(nbr->crypt_seqnum));
332 return 0;
333 }
334
335 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000336 memset(&ctx, 0, sizeof(ctx));
337 MD5Init(&ctx);
338 MD5Update(&ctx, ibuf, length);
339 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
340 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000341
342 /* compare the two */
343 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
344 {
345 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
346 IF_NAME (oi));
347 return 0;
348 }
349
350 /* save neighbor's crypt_seqnum */
351 if (nbr)
352 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
353 return 1;
354}
355
356/* This function is called from ospf_write(), it will detect the
357 authentication scheme and if it is MD5, it will change the sequence
358 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000359static int
paul718e3742002-12-13 20:15:29 +0000360ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
361{
362 struct ospf_header *ospfh;
363 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000364 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000365 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000366 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000367 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000368 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000369
370 ibuf = STREAM_DATA (op->s);
371 ospfh = (struct ospf_header *) ibuf;
372
373 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
374 return 0;
375
376 /* We do this here so when we dup a packet, we don't have to
Paul Jakma2518efd2006-08-27 06:49:29 +0000377 waste CPU rewriting other headers.
378
379 Note that quagga_time /deliberately/ is not used here */
paul9483e152002-12-13 20:55:25 +0000380 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000381 if (t > oi->crypt_seqnum)
382 oi->crypt_seqnum = t;
383 else
384 oi->crypt_seqnum++;
385
paul9483e152002-12-13 20:55:25 +0000386 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000387
388 /* Get MD5 Authentication key from auth_key list. */
389 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000390 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000391 else
392 {
paul1eb8ef22005-04-07 07:30:20 +0000393 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000394 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000395 }
396
397 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000398 memset(&ctx, 0, sizeof(ctx));
399 MD5Init(&ctx);
400 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
401 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
402 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000403
404 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000405 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000406
407 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000408 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
409
paul37163d62003-02-03 18:40:56 +0000410 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000411 /* XXX size_t */
412 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
413 (u_long)stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000414
415 return OSPF_AUTH_MD5_SIZE;
416}
417
418
paul4dadc292005-05-06 21:37:42 +0000419static int
paul718e3742002-12-13 20:15:29 +0000420ospf_ls_req_timer (struct thread *thread)
421{
422 struct ospf_neighbor *nbr;
423
424 nbr = THREAD_ARG (thread);
425 nbr->t_ls_req = NULL;
426
427 /* Send Link State Request. */
428 if (ospf_ls_request_count (nbr))
429 ospf_ls_req_send (nbr);
430
431 /* Set Link State Request retransmission timer. */
432 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
433
434 return 0;
435}
436
437void
438ospf_ls_req_event (struct ospf_neighbor *nbr)
439{
440 if (nbr->t_ls_req)
441 {
442 thread_cancel (nbr->t_ls_req);
443 nbr->t_ls_req = NULL;
444 }
445 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
446}
447
448/* Cyclic timer function. Fist registered in ospf_nbr_new () in
449 ospf_neighbor.c */
450int
451ospf_ls_upd_timer (struct thread *thread)
452{
453 struct ospf_neighbor *nbr;
454
455 nbr = THREAD_ARG (thread);
456 nbr->t_ls_upd = NULL;
457
458 /* Send Link State Update. */
459 if (ospf_ls_retransmit_count (nbr) > 0)
460 {
hasso52dc7ee2004-09-23 19:18:23 +0000461 struct list *update;
paul718e3742002-12-13 20:15:29 +0000462 struct ospf_lsdb *lsdb;
463 int i;
paul718e3742002-12-13 20:15:29 +0000464 int retransmit_interval;
465
paul718e3742002-12-13 20:15:29 +0000466 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
467
468 lsdb = &nbr->ls_rxmt;
469 update = list_new ();
470
471 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
472 {
473 struct route_table *table = lsdb->type[i].db;
474 struct route_node *rn;
475
476 for (rn = route_top (table); rn; rn = route_next (rn))
477 {
478 struct ospf_lsa *lsa;
479
480 if ((lsa = rn->info) != NULL)
481 /* Don't retransmit an LSA if we received it within
482 the last RxmtInterval seconds - this is to allow the
483 neighbour a chance to acknowledge the LSA as it may
484 have ben just received before the retransmit timer
485 fired. This is a small tweak to what is in the RFC,
486 but it will cut out out a lot of retransmit traffic
487 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000488 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000489 int2tv (retransmit_interval)) >= 0)
490 listnode_add (update, rn->info);
491 }
492 }
493
494 if (listcount (update) > 0)
495 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
496 list_delete (update);
497 }
498
499 /* Set LS Update retransmission timer. */
500 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
501
502 return 0;
503}
504
505int
506ospf_ls_ack_timer (struct thread *thread)
507{
508 struct ospf_interface *oi;
509
510 oi = THREAD_ARG (thread);
511 oi->t_ls_ack = NULL;
512
513 /* Send Link State Acknowledgment. */
514 if (listcount (oi->ls_ack) > 0)
515 ospf_ls_ack_send_delayed (oi);
516
517 /* Set LS Ack timer. */
518 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
519
520 return 0;
521}
522
paul0bfeca32004-09-24 08:07:54 +0000523#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000524static void
paul6a99f832004-09-27 12:56:30 +0000525ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000526 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000527 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000528{
529#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000530 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000531 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000532 int ret;
paul0bfeca32004-09-24 08:07:54 +0000533
534 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000535 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000536
537 /* we can but try.
538 *
539 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
540 * well as the IP_MF flag, making this all quite pointless.
541 *
542 * However, for a system on which IP_MF is left alone, and ip_id left
543 * alone or else which sets same ip_id for each fragment this might
544 * work, eg linux.
545 *
546 * XXX-TODO: It would be much nicer to have the kernel's use their
547 * existing fragmentation support to do this for us. Bugs/RFEs need to
548 * be raised against the various kernels.
549 */
550
551 /* set More Frag */
552 iph->ip_off |= IP_MF;
553
554 /* ip frag offset is expressed in units of 8byte words */
555 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
556
paul62d8e962004-11-02 20:26:45 +0000557 iovp = &msg->msg_iov[1];
558
paul0bfeca32004-09-24 08:07:54 +0000559 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
560 > maxdatasize )
561 {
562 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000563 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
564 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000565 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000566
paul18b12c32004-10-05 14:38:29 +0000567 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000568
paul6a99f832004-09-27 12:56:30 +0000569 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000570
paul18b12c32004-10-05 14:38:29 +0000571 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000572
573 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000574 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000575 " id %d, off %d, len %d, mtu %u failed with %s",
576 inet_ntoa (iph->ip_dst),
577 iph->ip_id,
578 iph->ip_off,
579 iph->ip_len,
580 mtu,
581 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000582
paul37ccfa32004-10-31 11:24:51 +0000583 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
584 {
ajs2a42e282004-12-08 18:43:03 +0000585 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000586 iph->ip_id, iph->ip_off, iph->ip_len,
587 inet_ntoa (iph->ip_dst));
588 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
589 {
ajs2a42e282004-12-08 18:43:03 +0000590 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000591 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000592 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000593 }
594 }
595
paul0bfeca32004-09-24 08:07:54 +0000596 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000597 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000598 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000599 }
600
601 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000602 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
603 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000604 iph->ip_off &= (~IP_MF);
605}
606#endif /* WANT_OSPF_WRITE_FRAGMENT */
607
ajs5dcbdf82005-03-29 16:13:49 +0000608static int
paul718e3742002-12-13 20:15:29 +0000609ospf_write (struct thread *thread)
610{
paul68980082003-03-25 05:07:42 +0000611 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000612 struct ospf_interface *oi;
613 struct ospf_packet *op;
614 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000615 struct ip iph;
616 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000617 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000618 u_char type;
619 int ret;
620 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000621 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000622#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000623 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000624#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000625 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000626#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000627
paul68980082003-03-25 05:07:42 +0000628 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000629
paul68980082003-03-25 05:07:42 +0000630 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000631 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000632 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000633 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000634
635#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000636 /* seed ipid static with low order bits of time */
637 if (ipid == 0)
638 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000639#endif /* WANT_OSPF_WRITE_FRAGMENT */
640
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000641 /* convenience - max OSPF data per packet,
642 * and reliability - not more data, than our
643 * socket can accept
644 */
645 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
646 sizeof (struct ip);
paul68b73392004-09-12 14:21:37 +0000647
paul718e3742002-12-13 20:15:29 +0000648 /* Get one packet from queue. */
649 op = ospf_fifo_head (oi->obuf);
650 assert (op);
651 assert (op->length >= OSPF_HEADER_SIZE);
652
paul68980082003-03-25 05:07:42 +0000653 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
654 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000655 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
656
paul718e3742002-12-13 20:15:29 +0000657 /* Rewrite the md5 signature & update the seq */
658 ospf_make_md5_digest (oi, op);
659
paul37ccfa32004-10-31 11:24:51 +0000660 /* Retrieve OSPF packet type. */
661 stream_set_getp (op->s, 1);
662 type = stream_getc (op->s);
663
paul68b73392004-09-12 14:21:37 +0000664 /* reset get pointer */
665 stream_set_getp (op->s, 0);
666
667 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000668 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000669
paul718e3742002-12-13 20:15:29 +0000670 sa_dst.sin_family = AF_INET;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000671#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +0000672 sa_dst.sin_len = sizeof(sa_dst);
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000673#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +0000674 sa_dst.sin_addr = op->dst;
675 sa_dst.sin_port = htons (0);
676
677 /* Set DONTROUTE flag if dst is unicast. */
678 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
679 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
680 flags = MSG_DONTROUTE;
681
paul68b73392004-09-12 14:21:37 +0000682 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
683 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000684 if ( sizeof (struct ip)
685 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000686 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
687
paul718e3742002-12-13 20:15:29 +0000688 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000689 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000690 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000691
David BÉRARD0150c9c2010-05-11 10:17:53 +0200692#if defined(__DragonFly__)
693 /*
694 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
695 */
696 iph.ip_len = htons(iph.ip_len);
697#endif
698
paul0bfeca32004-09-24 08:07:54 +0000699#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000700 /* XXX-MT: not thread-safe at all..
701 * XXX: this presumes this is only programme sending OSPF packets
702 * otherwise, no guarantee ipid will be unique
703 */
704 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000705#endif /* WANT_OSPF_WRITE_FRAGMENT */
706
paul718e3742002-12-13 20:15:29 +0000707 iph.ip_off = 0;
708 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
709 iph.ip_ttl = OSPF_VL_IP_TTL;
710 else
711 iph.ip_ttl = OSPF_IP_TTL;
712 iph.ip_p = IPPROTO_OSPFIGP;
713 iph.ip_sum = 0;
714 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
715 iph.ip_dst.s_addr = op->dst.s_addr;
716
717 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000718 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000719 msg.msg_namelen = sizeof (sa_dst);
720 msg.msg_iov = iov;
721 msg.msg_iovlen = 2;
722 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000723 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
724 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000725 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000726
727 /* Sadly we can not rely on kernels to fragment packets because of either
728 * IP_HDRINCL and/or multicast destination being set.
729 */
paul0bfeca32004-09-24 08:07:54 +0000730#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000731 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000732 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
733 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000734#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000735
736 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000737 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000738 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000739 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000740
741 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000742 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000743 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000744 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000745 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000746
paul718e3742002-12-13 20:15:29 +0000747 /* Show debug sending packet. */
748 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
749 {
750 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
751 {
ajs2a42e282004-12-08 18:43:03 +0000752 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000753 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000754 stream_set_getp (op->s, 0);
755 ospf_packet_dump (op->s);
756 }
757
ajs2a42e282004-12-08 18:43:03 +0000758 zlog_debug ("%s sent to [%s] via [%s].",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400759 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
paul718e3742002-12-13 20:15:29 +0000760 IF_NAME (oi));
761
762 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000763 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000764 }
765
766 /* Now delete packet from queue. */
767 ospf_packet_delete (oi);
768
769 if (ospf_fifo_head (oi->obuf) == NULL)
770 {
771 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000772 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000773 }
774
775 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000776 if (!list_isempty (ospf->oi_write_q))
777 ospf->t_write =
778 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000779
780 return 0;
781}
782
783/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000784static void
paul718e3742002-12-13 20:15:29 +0000785ospf_hello (struct ip *iph, struct ospf_header *ospfh,
786 struct stream * s, struct ospf_interface *oi, int size)
787{
788 struct ospf_hello *hello;
789 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000790 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000791 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000792
793 /* increment statistics. */
794 oi->hello_in++;
795
796 hello = (struct ospf_hello *) STREAM_PNT (s);
797
798 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000799 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000800 {
801 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
802 {
ajs2a42e282004-12-08 18:43:03 +0000803 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000804 "dropping.",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400805 LOOKUP (ospf_packet_type_str, ospfh->type),
pauld3241812003-09-29 12:42:39 +0000806 inet_ntoa (iph->ip_src));
807 }
808 return;
809 }
paul718e3742002-12-13 20:15:29 +0000810
paul718e3742002-12-13 20:15:29 +0000811 /* get neighbor prefix. */
812 p.family = AF_INET;
813 p.prefixlen = ip_masklen (hello->network_mask);
814 p.u.prefix4 = iph->ip_src;
815
816 /* Compare network mask. */
817 /* Checking is ignored for Point-to-Point and Virtual link. */
818 if (oi->type != OSPF_IFTYPE_POINTOPOINT
819 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
820 if (oi->address->prefixlen != p.prefixlen)
821 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000822 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
823 inet_ntoa(ospfh->router_id), IF_NAME(oi),
824 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000825 return;
826 }
827
paul718e3742002-12-13 20:15:29 +0000828 /* Compare Router Dead Interval. */
829 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
830 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000831 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
832 "(expected %u, but received %u).",
833 inet_ntoa(ospfh->router_id),
834 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000835 return;
836 }
837
paulf9ad9372005-10-21 00:45:17 +0000838 /* Compare Hello Interval - ignored if fast-hellos are set. */
839 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
840 {
841 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
842 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000843 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
844 "(expected %u, but received %u).",
845 inet_ntoa(ospfh->router_id),
846 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000847 return;
848 }
849 }
850
paul718e3742002-12-13 20:15:29 +0000851 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000852 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000853 inet_ntoa (ospfh->router_id),
854 ospf_options_dump (hello->options));
855
856 /* Compare options. */
857#define REJECT_IF_TBIT_ON 1 /* XXX */
858#ifdef REJECT_IF_TBIT_ON
859 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
860 {
861 /*
862 * This router does not support non-zero TOS.
863 * Drop this Hello packet not to establish neighbor relationship.
864 */
865 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
866 inet_ntoa (ospfh->router_id));
867 return;
868 }
869#endif /* REJECT_IF_TBIT_ON */
870
871#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000872 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000873 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
874 {
875 /*
876 * This router does know the correct usage of O-bit
877 * the bit should be set in DD packet only.
878 */
879 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
880 inet_ntoa (ospfh->router_id));
881#ifdef STRICT_OBIT_USAGE_CHECK
882 return; /* Reject this packet. */
883#else /* STRICT_OBIT_USAGE_CHECK */
884 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
885#endif /* STRICT_OBIT_USAGE_CHECK */
886 }
887#endif /* HAVE_OPAQUE_LSA */
888
889 /* new for NSSA is to ensure that NP is on and E is off */
890
paul718e3742002-12-13 20:15:29 +0000891 if (oi->area->external_routing == OSPF_AREA_NSSA)
892 {
893 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
894 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
895 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
896 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
897 {
898 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
899 return;
900 }
901 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000902 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000903 }
904 else
paul718e3742002-12-13 20:15:29 +0000905 /* The setting of the E-bit found in the Hello Packet's Options
906 field must match this area's ExternalRoutingCapability A
907 mismatch causes processing to stop and the packet to be
908 dropped. The setting of the rest of the bits in the Hello
909 Packet's Options field should be ignored. */
910 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
911 CHECK_FLAG (hello->options, OSPF_OPTION_E))
912 {
ajs3aa8d5f2004-12-11 18:00:06 +0000913 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
914 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000915 return;
916 }
paul718e3742002-12-13 20:15:29 +0000917
pauld3f0d622004-05-05 15:27:15 +0000918 /* get neighbour struct */
919 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
920
921 /* neighbour must be valid, ospf_nbr_get creates if none existed */
922 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000923
924 old_state = nbr->state;
925
926 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000927 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000928
929 /* RFC2328 Section 9.5.1
930 If the router is not eligible to become Designated Router,
931 (snip) It must also send an Hello Packet in reply to an
932 Hello Packet received from any eligible neighbor (other than
933 the current Designated Router and Backup Designated Router). */
934 if (oi->type == OSPF_IFTYPE_NBMA)
935 if (PRIORITY(oi) == 0 && hello->priority > 0
936 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
937 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
938 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
939 OSPF_HELLO_REPLY_DELAY);
940
941 /* on NBMA network type, it happens to receive bidirectional Hello packet
942 without advance 1-Way Received event.
943 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
944 if (oi->type == OSPF_IFTYPE_NBMA &&
945 (old_state == NSM_Down || old_state == NSM_Attempt))
946 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000947 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000948 nbr->priority = hello->priority;
949 nbr->d_router = hello->d_router;
950 nbr->bd_router = hello->bd_router;
951 return;
952 }
953
paul68980082003-03-25 05:07:42 +0000954 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000955 size - OSPF_HELLO_MIN_SIZE))
956 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000957 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000958 nbr->options |= hello->options;
959 }
960 else
961 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000962 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000963 /* Set neighbor information. */
964 nbr->priority = hello->priority;
965 nbr->d_router = hello->d_router;
966 nbr->bd_router = hello->bd_router;
967 return;
968 }
969
970 /* If neighbor itself declares DR and no BDR exists,
971 cause event BackupSeen */
972 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
973 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
974 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
975
976 /* neighbor itself declares BDR. */
977 if (oi->state == ISM_Waiting &&
978 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
979 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
980
981 /* had not previously. */
982 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
983 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
984 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
985 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
986 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
987
988 /* had not previously. */
989 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
990 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
991 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
992 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
993 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
994
995 /* Neighbor priority check. */
996 if (nbr->priority >= 0 && nbr->priority != hello->priority)
997 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
998
999 /* Set neighbor information. */
1000 nbr->priority = hello->priority;
1001 nbr->d_router = hello->d_router;
1002 nbr->bd_router = hello->bd_router;
1003}
1004
1005/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +00001006static void
paul718e3742002-12-13 20:15:29 +00001007ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1008 struct ospf_db_desc *dd)
1009{
1010 nbr->last_recv.flags = dd->flags;
1011 nbr->last_recv.options = dd->options;
1012 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1013}
1014
1015/* Process rest of DD packet. */
1016static void
1017ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1018 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1019 u_int16_t size)
1020{
1021 struct ospf_lsa *new, *find;
1022 struct lsa_header *lsah;
1023
paul9985f832005-02-09 15:51:56 +00001024 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001025 for (size -= OSPF_DB_DESC_MIN_SIZE;
1026 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1027 {
1028 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001029 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001030
1031 /* Unknown LS type. */
1032 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1033 {
ajsbec595a2004-11-30 22:38:43 +00001034 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001035 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1036 return;
1037 }
1038
1039#ifdef HAVE_OPAQUE_LSA
1040 if (IS_OPAQUE_LSA (lsah->type)
1041 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1042 {
1043 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1044 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1045 return;
1046 }
1047#endif /* HAVE_OPAQUE_LSA */
1048
1049 switch (lsah->type)
1050 {
1051 case OSPF_AS_EXTERNAL_LSA:
1052#ifdef HAVE_OPAQUE_LSA
1053 case OSPF_OPAQUE_AS_LSA:
1054#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001055 /* Check for stub area. Reject if AS-External from stub but
1056 allow if from NSSA. */
1057 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001058 {
1059 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1060 lsah->type, inet_ntoa (lsah->id),
1061 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1062 "STUB" : "NSSA");
1063 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1064 return;
1065 }
1066 break;
1067 default:
1068 break;
1069 }
1070
1071 /* Create LS-request object. */
1072 new = ospf_ls_request_new (lsah);
1073
1074 /* Lookup received LSA, then add LS request list. */
1075 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001076
1077 /* ospf_lsa_more_recent is fine with NULL pointers */
1078 switch (ospf_lsa_more_recent (find, new))
1079 {
1080 case -1:
1081 /* Neighbour has a more recent LSA, we must request it */
1082 ospf_ls_request_add (nbr, new);
1083 case 0:
1084 /* If we have a copy of this LSA, it's either less recent
1085 * and we're requesting it from neighbour (the case above), or
1086 * it's as recent and we both have same copy (this case).
1087 *
1088 * In neither of these two cases is there any point in
1089 * describing our copy of the LSA to the neighbour in a
1090 * DB-Summary packet, if we're still intending to do so.
1091 *
1092 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1093 * backward compatible optimisation to OSPF DB Exchange /
1094 * DB Description process implemented here.
1095 */
1096 if (find)
1097 ospf_lsdb_delete (&nbr->db_sum, find);
1098 ospf_lsa_discard (new);
1099 break;
1100 default:
1101 /* We have the more recent copy, nothing specific to do:
1102 * - no need to request neighbours stale copy
1103 * - must leave DB summary list copy alone
1104 */
1105 if (IS_DEBUG_OSPF_EVENT)
1106 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1107 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1108 ospf_lsa_discard (new);
1109 }
paul718e3742002-12-13 20:15:29 +00001110 }
1111
1112 /* Master */
1113 if (IS_SET_DD_MS (nbr->dd_flags))
1114 {
1115 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001116
1117 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001118 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1119 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1120 else
paul718e3742002-12-13 20:15:29 +00001121 ospf_db_desc_send (nbr);
1122 }
1123 /* Slave */
1124 else
1125 {
1126 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1127
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001128 /* Send DD packet in reply.
1129 *
1130 * Must be done to acknowledge the Master's DD, regardless of
1131 * whether we have more LSAs ourselves to describe.
1132 *
1133 * This function will clear the 'More' bit, if after this DD
1134 * we have no more LSAs to describe to the master..
1135 */
paul718e3742002-12-13 20:15:29 +00001136 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001137
1138 /* Slave can raise ExchangeDone now, if master is also done */
1139 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1140 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001141 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001142
paul718e3742002-12-13 20:15:29 +00001143 /* Save received neighbor values from DD. */
1144 ospf_db_desc_save_current (nbr, dd);
1145}
1146
paul4dadc292005-05-06 21:37:42 +00001147static int
paul718e3742002-12-13 20:15:29 +00001148ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1149{
1150 /* Is DD duplicated? */
1151 if (dd->options == nbr->last_recv.options &&
1152 dd->flags == nbr->last_recv.flags &&
1153 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1154 return 1;
1155
1156 return 0;
1157}
1158
1159/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001160static void
paul718e3742002-12-13 20:15:29 +00001161ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1162 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1163{
1164 struct ospf_db_desc *dd;
1165 struct ospf_neighbor *nbr;
1166
1167 /* Increment statistics. */
1168 oi->db_desc_in++;
1169
1170 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001171
pauld3f0d622004-05-05 15:27:15 +00001172 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001173 if (nbr == NULL)
1174 {
1175 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1176 inet_ntoa (ospfh->router_id));
1177 return;
1178 }
1179
1180 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001181 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1182 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001183 {
ajs3aa8d5f2004-12-11 18:00:06 +00001184 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1185 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1186 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001187 return;
1188 }
1189
pauld363df22003-06-19 00:26:34 +00001190 /*
1191 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1192 * required. In fact at least JunOS sends DD packets with P bit clear.
1193 * Until proper solution is developped, this hack should help.
1194 *
1195 * Update: According to the RFCs, N bit is specified /only/ for Hello
1196 * options, unfortunately its use in DD options is not specified. Hence some
1197 * implementations follow E-bit semantics and set it in DD options, and some
1198 * treat it as unspecified and hence follow the directive "default for
1199 * options is clear", ie unset.
1200 *
1201 * Reset the flag, as ospfd follows E-bit semantics.
1202 */
1203 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1204 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1205 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1206 {
1207 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001208 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001209 inet_ntoa (nbr->router_id) );
1210 SET_FLAG (dd->options, OSPF_OPTION_NP);
1211 }
pauld363df22003-06-19 00:26:34 +00001212
paul718e3742002-12-13 20:15:29 +00001213#ifdef REJECT_IF_TBIT_ON
1214 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1215 {
1216 /*
1217 * In Hello protocol, optional capability must have checked
1218 * to prevent this T-bit enabled router be my neighbor.
1219 */
1220 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1221 return;
1222 }
1223#endif /* REJECT_IF_TBIT_ON */
1224
1225#ifdef HAVE_OPAQUE_LSA
1226 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001227 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001228 {
1229 /*
1230 * This node is not configured to handle O-bit, for now.
1231 * Clear it to ignore unsupported capability proposed by neighbor.
1232 */
1233 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1234 }
1235#endif /* HAVE_OPAQUE_LSA */
1236
Paul Jakma57c5c652010-01-07 06:12:53 +00001237 /* Add event to thread. */
1238 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1239
paul718e3742002-12-13 20:15:29 +00001240 /* Process DD packet by neighbor status. */
1241 switch (nbr->state)
1242 {
1243 case NSM_Down:
1244 case NSM_Attempt:
1245 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001246 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001247 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001248 LOOKUP (ospf_nsm_state_msg, nbr->state));
1249 break;
1250 case NSM_Init:
1251 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1252 /* If the new state is ExStart, the processing of the current
1253 packet should then continue in this new state by falling
1254 through to case ExStart below. */
1255 if (nbr->state != NSM_ExStart)
1256 break;
1257 case NSM_ExStart:
1258 /* Initial DBD */
1259 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1260 (size == OSPF_DB_DESC_MIN_SIZE))
1261 {
paul68980082003-03-25 05:07:42 +00001262 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001263 {
1264 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001265 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001266 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001267 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001268
1269 /* Reset I/MS */
1270 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001271 }
1272 else
1273 {
1274 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001275 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001276 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001277 break;
1278 }
1279 }
1280 /* Ack from the Slave */
1281 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1282 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001283 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001284 {
ajs17eaa722004-12-29 21:04:48 +00001285 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001286 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001287 /* Reset I, leaving MS */
1288 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001289 }
1290 else
1291 {
ajs3aa8d5f2004-12-11 18:00:06 +00001292 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1293 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001294 break;
1295 }
1296
1297 /* This is where the real Options are saved */
1298 nbr->options = dd->options;
1299
1300#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001301 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001302 {
1303 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001304 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001305 inet_ntoa (nbr->router_id),
1306 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1307
1308 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1309 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1310 {
paul6d452762005-11-03 11:15:44 +00001311 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1312 "Opaque-LSAs cannot be reliably advertised "
1313 "in this network.",
1314 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001315 /* This situation is undesirable, but not a real error. */
1316 }
1317 }
1318#endif /* HAVE_OPAQUE_LSA */
1319
1320 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1321
1322 /* continue processing rest of packet. */
1323 ospf_db_desc_proc (s, oi, nbr, dd, size);
1324 break;
1325 case NSM_Exchange:
1326 if (ospf_db_desc_is_dup (dd, nbr))
1327 {
1328 if (IS_SET_DD_MS (nbr->dd_flags))
1329 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001330 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001331 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001332 else
1333 /* Slave: cause to retransmit the last Database Description. */
1334 {
paul6d452762005-11-03 11:15:44 +00001335 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001336 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001337 ospf_db_desc_resend (nbr);
1338 }
1339 break;
1340 }
1341
1342 /* Otherwise DD packet should be checked. */
1343 /* Check Master/Slave bit mismatch */
1344 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1345 {
ajs3aa8d5f2004-12-11 18:00:06 +00001346 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1347 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001348 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1349 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001350 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001351 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001352 break;
1353 }
1354
1355 /* Check initialize bit is set. */
1356 if (IS_SET_DD_I (dd->flags))
1357 {
paul6d452762005-11-03 11:15:44 +00001358 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001359 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001360 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1361 break;
1362 }
1363
1364 /* Check DD Options. */
1365 if (dd->options != nbr->options)
1366 {
1367#ifdef ORIGINAL_CODING
1368 /* Save the new options for debugging */
1369 nbr->options = dd->options;
1370#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001371 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1372 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001373 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1374 break;
1375 }
1376
1377 /* Check DD sequence number. */
1378 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1379 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1380 (!IS_SET_DD_MS (nbr->dd_flags) &&
1381 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1382 {
ajs3aa8d5f2004-12-11 18:00:06 +00001383 zlog_warn ("Packet[DD]: Neighbor %s sequence number 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 /* Continue processing rest of packet. */
1390 ospf_db_desc_proc (s, oi, nbr, dd, size);
1391 break;
1392 case NSM_Loading:
1393 case NSM_Full:
1394 if (ospf_db_desc_is_dup (dd, nbr))
1395 {
1396 if (IS_SET_DD_MS (nbr->dd_flags))
1397 {
1398 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001399 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1400 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001401 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001402 break;
1403 }
1404 else
1405 {
1406 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001407 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001408 t = tv_sub (now, nbr->last_send_ts);
1409 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1410 {
1411 /* In states Loading and Full the slave must resend
1412 its last Database Description packet in response to
1413 duplicate Database Description packets received
1414 from the master. For this reason the slave must
1415 wait RouterDeadInterval seconds before freeing the
1416 last Database Description packet. Reception of a
1417 Database Description packet from the master after
1418 this interval will generate a SeqNumberMismatch
1419 neighbor event. RFC2328 Section 10.8 */
1420 ospf_db_desc_resend (nbr);
1421 break;
1422 }
1423 }
1424 }
1425
1426 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1427 break;
1428 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001429 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1430 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001431 break;
1432 }
1433}
1434
1435#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1436
1437/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001438static void
paul718e3742002-12-13 20:15:29 +00001439ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1440 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1441{
1442 struct ospf_neighbor *nbr;
1443 u_int32_t ls_type;
1444 struct in_addr ls_id;
1445 struct in_addr adv_router;
1446 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001447 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001448 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001449
1450 /* Increment statistics. */
1451 oi->ls_req_in++;
1452
pauld3f0d622004-05-05 15:27:15 +00001453 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001454 if (nbr == NULL)
1455 {
1456 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1457 inet_ntoa (ospfh->router_id));
1458 return;
1459 }
1460
Paul Jakma57c5c652010-01-07 06:12:53 +00001461 /* Add event to thread. */
1462 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1463
paul718e3742002-12-13 20:15:29 +00001464 /* Neighbor State should be Exchange or later. */
1465 if (nbr->state != NSM_Exchange &&
1466 nbr->state != NSM_Loading &&
1467 nbr->state != NSM_Full)
1468 {
ajsbec595a2004-11-30 22:38:43 +00001469 zlog_warn ("Link State Request received from %s: "
1470 "Neighbor state is %s, packet discarded.",
1471 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001472 LOOKUP (ospf_nsm_state_msg, nbr->state));
1473 return;
1474 }
1475
1476 /* Send Link State Update for ALL requested LSAs. */
1477 ls_upd = list_new ();
1478 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1479
1480 while (size >= OSPF_LSA_KEY_SIZE)
1481 {
1482 /* Get one slice of Link State Request. */
1483 ls_type = stream_getl (s);
1484 ls_id.s_addr = stream_get_ipv4 (s);
1485 adv_router.s_addr = stream_get_ipv4 (s);
1486
1487 /* Verify LSA type. */
1488 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1489 {
1490 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1491 list_delete (ls_upd);
1492 return;
1493 }
1494
1495 /* Search proper LSA in LSDB. */
1496 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1497 if (find == NULL)
1498 {
1499 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1500 list_delete (ls_upd);
1501 return;
1502 }
1503
gdt86f1fd92005-01-10 14:20:43 +00001504 /* Packet overflows MTU size, send immediately. */
1505 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001506 {
1507 if (oi->type == OSPF_IFTYPE_NBMA)
1508 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1509 else
1510 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1511
1512 /* Only remove list contents. Keep ls_upd. */
1513 list_delete_all_node (ls_upd);
1514
1515 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1516 }
1517
1518 /* Append LSA to update list. */
1519 listnode_add (ls_upd, find);
1520 length += ntohs (find->data->length);
1521
1522 size -= OSPF_LSA_KEY_SIZE;
1523 }
1524
1525 /* Send rest of Link State Update. */
1526 if (listcount (ls_upd) > 0)
1527 {
1528 if (oi->type == OSPF_IFTYPE_NBMA)
1529 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1530 else
1531 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1532
1533 list_delete (ls_upd);
1534 }
1535 else
1536 list_free (ls_upd);
1537}
1538
1539/* Get the list of LSAs from Link State Update packet.
1540 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001541static struct list *
paul718e3742002-12-13 20:15:29 +00001542ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1543 struct ospf_interface *oi, size_t size)
1544{
1545 u_int16_t count, sum;
1546 u_int32_t length;
1547 struct lsa_header *lsah;
1548 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001549 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001550
1551 lsas = list_new ();
1552
1553 count = stream_getl (s);
1554 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1555
1556 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001557 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001558 {
1559 lsah = (struct lsa_header *) STREAM_PNT (s);
1560 length = ntohs (lsah->length);
1561
1562 if (length > size)
1563 {
1564 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1565 break;
1566 }
1567
1568 /* Validate the LSA's LS checksum. */
1569 sum = lsah->checksum;
1570 if (sum != ospf_lsa_checksum (lsah))
1571 {
Jaroslav Fojtik223da1a2011-12-11 18:22:16 +04001572 /* (bug #685) more details in a one-line message make it possible
1573 * to identify problem source on the one hand and to have a better
1574 * chance to compress repeated messages in syslog on the other */
1575 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1576 sum, lsah->checksum, inet_ntoa (lsah->id),
1577 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1578 inet_ntoa (lsah->adv_router));
paul718e3742002-12-13 20:15:29 +00001579 continue;
1580 }
1581
1582 /* Examine the LSA's LS type. */
1583 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1584 {
1585 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1586 continue;
1587 }
1588
1589 /*
1590 * What if the received LSA's age is greater than MaxAge?
1591 * Treat it as a MaxAge case -- endo.
1592 */
1593 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1594 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1595
1596#ifdef HAVE_OPAQUE_LSA
1597 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1598 {
1599#ifdef STRICT_OBIT_USAGE_CHECK
1600 if ((IS_OPAQUE_LSA(lsah->type) &&
1601 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1602 || (! IS_OPAQUE_LSA(lsah->type) &&
1603 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1604 {
1605 /*
1606 * This neighbor must know the exact usage of O-bit;
1607 * the bit will be set in Type-9,10,11 LSAs only.
1608 */
1609 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1610 continue;
1611 }
1612#endif /* STRICT_OBIT_USAGE_CHECK */
1613
1614 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1615 if (lsah->type == OSPF_OPAQUE_AS_LSA
1616 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1617 {
1618 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001619 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 +00001620 continue;
1621 }
1622 }
1623 else if (IS_OPAQUE_LSA(lsah->type))
1624 {
1625 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1626 continue;
1627 }
1628#endif /* HAVE_OPAQUE_LSA */
1629
1630 /* Create OSPF LSA instance. */
1631 lsa = ospf_lsa_new ();
1632
1633 /* We may wish to put some error checking if type NSSA comes in
1634 and area not in NSSA mode */
1635 switch (lsah->type)
1636 {
1637 case OSPF_AS_EXTERNAL_LSA:
1638#ifdef HAVE_OPAQUE_LSA
1639 case OSPF_OPAQUE_AS_LSA:
1640 lsa->area = NULL;
1641 break;
1642 case OSPF_OPAQUE_LINK_LSA:
1643 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1644 /* Fallthrough */
1645#endif /* HAVE_OPAQUE_LSA */
1646 default:
1647 lsa->area = oi->area;
1648 break;
1649 }
1650
1651 lsa->data = ospf_lsa_data_new (length);
1652 memcpy (lsa->data, lsah, length);
1653
1654 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001655 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001656 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1657 listnode_add (lsas, lsa);
1658 }
1659
1660 return lsas;
1661}
1662
1663/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001664static void
hasso52dc7ee2004-09-23 19:18:23 +00001665ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001666{
paul1eb8ef22005-04-07 07:30:20 +00001667 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001668 struct ospf_lsa *lsa;
1669
paul1eb8ef22005-04-07 07:30:20 +00001670 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1671 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001672
1673 list_delete (lsas);
1674}
1675
1676/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001677static void
paul718e3742002-12-13 20:15:29 +00001678ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1679 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1680{
1681 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001682 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001683 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001684 struct ospf_lsa *lsa = NULL;
1685 /* unsigned long ls_req_found = 0; */
1686
1687 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1688
1689 /* Increment statistics. */
1690 oi->ls_upd_in++;
1691
1692 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001693 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001694 if (nbr == NULL)
1695 {
1696 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1697 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1698 return;
1699 }
1700
Paul Jakma57c5c652010-01-07 06:12:53 +00001701 /* Add event to thread. */
1702 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1703
paul718e3742002-12-13 20:15:29 +00001704 /* Check neighbor state. */
1705 if (nbr->state < NSM_Exchange)
1706 {
ajs3aa8d5f2004-12-11 18:00:06 +00001707 zlog_warn ("Link State Update: "
1708 "Neighbor[%s] state %s is less than Exchange",
1709 inet_ntoa (ospfh->router_id),
1710 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001711 return;
1712 }
1713
1714 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1715 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1716 * of section 13.
1717 */
1718 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1719
1720#ifdef HAVE_OPAQUE_LSA
1721 /*
paul718e3742002-12-13 20:15:29 +00001722 * If self-originated Opaque-LSAs that have flooded before restart
1723 * are contained in the received LSUpd message, corresponding LSReq
1724 * messages to be sent may have to be modified.
1725 * To eliminate possible race conditions such that flushing and normal
1726 * updating for the same LSA would take place alternately, this trick
1727 * must be done before entering to the loop below.
1728 */
paul69310a62005-05-11 18:09:59 +00001729 /* XXX: Why is this Opaque specific? Either our core code is deficient
1730 * and this should be fixed generally, or Opaque is inventing strawman
1731 * problems */
paul718e3742002-12-13 20:15:29 +00001732 ospf_opaque_adjust_lsreq (nbr, lsas);
1733#endif /* HAVE_OPAQUE_LSA */
1734
1735#define DISCARD_LSA(L,N) {\
1736 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001737 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 +00001738 ospf_lsa_discard (L); \
1739 continue; }
1740
1741 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001742 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001743 {
1744 struct ospf_lsa *ls_ret, *current;
1745 int ret = 1;
1746
paul718e3742002-12-13 20:15:29 +00001747 if (IS_DEBUG_OSPF_NSSA)
1748 {
1749 char buf1[INET_ADDRSTRLEN];
1750 char buf2[INET_ADDRSTRLEN];
1751 char buf3[INET_ADDRSTRLEN];
1752
ajs2a42e282004-12-08 18:43:03 +00001753 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001754 lsa->data->type,
1755 inet_ntop (AF_INET, &ospfh->router_id,
1756 buf1, INET_ADDRSTRLEN),
1757 inet_ntop (AF_INET, &lsa->data->id,
1758 buf2, INET_ADDRSTRLEN),
1759 inet_ntop (AF_INET, &lsa->data->adv_router,
1760 buf3, INET_ADDRSTRLEN));
1761 }
paul718e3742002-12-13 20:15:29 +00001762
1763 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1764
1765 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1766
1767 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1768
1769 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1770
1771 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1772
1773 /* Do take in Type-7's if we are an NSSA */
1774
1775 /* If we are also an ABR, later translate them to a Type-5 packet */
1776
1777 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1778 translate them to a separate Type-5 packet. */
1779
1780 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1781 /* Reject from STUB or NSSA */
1782 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1783 {
paul718e3742002-12-13 20:15:29 +00001784 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001785 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001786 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001787 }
1788
paul718e3742002-12-13 20:15:29 +00001789 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1790 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1791 {
paul718e3742002-12-13 20:15:29 +00001792 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001793 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001794 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001795 }
paul718e3742002-12-13 20:15:29 +00001796
1797 /* Find the LSA in the current database. */
1798
1799 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1800
1801 /* If the LSA's LS age is equal to MaxAge, and there is currently
1802 no instance of the LSA in the router's link state database,
1803 and none of router's neighbors are in states Exchange or Loading,
1804 then take the following actions. */
1805
1806 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001807 (ospf_nbr_count (oi, NSM_Exchange) +
1808 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001809 {
1810 /* Response Link State Acknowledgment. */
1811 ospf_ls_ack_send (nbr, lsa);
1812
1813 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001814 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1815 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001816 DISCARD_LSA (lsa, 3);
1817 }
1818
1819#ifdef HAVE_OPAQUE_LSA
1820 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001821 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001822 {
1823 /*
1824 * Even if initial flushing seems to be completed, there might
1825 * be a case that self-originated LSA with MaxAge still remain
1826 * in the routing domain.
1827 * Just send an LSAck message to cease retransmission.
1828 */
1829 if (IS_LSA_MAXAGE (lsa))
1830 {
1831 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1832 ospf_ls_ack_send (nbr, lsa);
1833 ospf_lsa_discard (lsa);
1834
1835 if (current != NULL && ! IS_LSA_MAXAGE (current))
1836 ospf_opaque_lsa_refresh_schedule (current);
1837 continue;
1838 }
1839
1840 /*
1841 * If an instance of self-originated Opaque-LSA is not found
1842 * in the LSDB, there are some possible cases here.
1843 *
1844 * 1) This node lost opaque-capability after restart.
1845 * 2) Else, a part of opaque-type is no more supported.
1846 * 3) Else, a part of opaque-id is no more supported.
1847 *
1848 * Anyway, it is still this node's responsibility to flush it.
1849 * Otherwise, the LSA instance remains in the routing domain
1850 * until its age reaches to MaxAge.
1851 */
paul69310a62005-05-11 18:09:59 +00001852 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001853 if (current == NULL)
1854 {
1855 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001856 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1857 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001858
1859 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001860
1861 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1862 ospf_ls_ack_send (nbr, lsa);
1863
paul718e3742002-12-13 20:15:29 +00001864 continue;
1865 }
1866 }
1867#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001868
hassocb05eb22004-02-11 21:10:19 +00001869 /* It might be happen that received LSA is self-originated network LSA, but
1870 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1871 * Link State ID is one of the router's own IP interface addresses but whose
1872 * Advertising Router is not equal to the router's own Router ID
1873 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1874 */
1875
1876 if(lsa->data->type == OSPF_NETWORK_LSA)
1877 {
paul1eb8ef22005-04-07 07:30:20 +00001878 struct listnode *oinode, *oinnode;
1879 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001880 int Flag = 0;
1881
paul1eb8ef22005-04-07 07:30:20 +00001882 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001883 {
hassocb05eb22004-02-11 21:10:19 +00001884 if(out_if == NULL)
1885 break;
1886
1887 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1888 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1889 {
1890 if(out_if->network_lsa_self)
1891 {
1892 ospf_lsa_flush_area(lsa,out_if->area);
1893 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001894 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001895 lsa, (int) lsa->data->type);
1896 ospf_lsa_discard (lsa);
1897 Flag = 1;
1898 }
1899 break;
1900 }
1901 }
1902 if(Flag)
1903 continue;
1904 }
paul718e3742002-12-13 20:15:29 +00001905
1906 /* (5) Find the instance of this LSA that is currently contained
1907 in the router's link state database. If there is no
1908 database copy, or the received LSA is more recent than
1909 the database copy the following steps must be performed. */
1910
1911 if (current == NULL ||
1912 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1913 {
1914 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001915 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001916 DISCARD_LSA (lsa, 4);
1917 continue;
1918 }
1919
1920 /* (6) Else, If there is an instance of the LSA on the sending
1921 neighbor's Link state request list, an error has occurred in
1922 the Database Exchange process. In this case, restart the
1923 Database Exchange process by generating the neighbor event
1924 BadLSReq for the sending neighbor and stop processing the
1925 Link State Update packet. */
1926
1927 if (ospf_ls_request_lookup (nbr, lsa))
1928 {
1929 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001930 zlog_warn("LSA[%s] instance exists on Link state request list",
1931 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001932
1933 /* Clean list of LSAs. */
1934 ospf_upd_list_clean (lsas);
1935 /* this lsa is not on lsas list already. */
1936 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001937 return;
1938 }
1939
1940 /* If the received LSA is the same instance as the database copy
1941 (i.e., neither one is more recent) the following two steps
1942 should be performed: */
1943
1944 if (ret == 0)
1945 {
1946 /* If the LSA is listed in the Link state retransmission list
1947 for the receiving adjacency, the router itself is expecting
1948 an acknowledgment for this LSA. The router should treat the
1949 received LSA as an acknowledgment by removing the LSA from
1950 the Link state retransmission list. This is termed an
1951 "implied acknowledgment". */
1952
1953 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1954
1955 if (ls_ret != NULL)
1956 {
1957 ospf_ls_retransmit_delete (nbr, ls_ret);
1958
1959 /* Delayed acknowledgment sent if advertisement received
1960 from Designated Router, otherwise do nothing. */
1961 if (oi->state == ISM_Backup)
1962 if (NBR_IS_DR (nbr))
1963 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1964
1965 DISCARD_LSA (lsa, 5);
1966 }
1967 else
1968 /* Acknowledge the receipt of the LSA by sending a
1969 Link State Acknowledgment packet back out the receiving
1970 interface. */
1971 {
1972 ospf_ls_ack_send (nbr, lsa);
1973 DISCARD_LSA (lsa, 6);
1974 }
1975 }
1976
1977 /* The database copy is more recent. If the database copy
1978 has LS age equal to MaxAge and LS sequence number equal to
1979 MaxSequenceNumber, simply discard the received LSA without
1980 acknowledging it. (In this case, the LSA's LS sequence number is
1981 wrapping, and the MaxSequenceNumber LSA must be completely
1982 flushed before any new LSA instance can be introduced). */
1983
1984 else if (ret > 0) /* Database copy is more recent */
1985 {
1986 if (IS_LSA_MAXAGE (current) &&
1987 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1988 {
1989 DISCARD_LSA (lsa, 7);
1990 }
1991 /* Otherwise, as long as the database copy has not been sent in a
1992 Link State Update within the last MinLSArrival seconds, send the
1993 database copy back to the sending neighbor, encapsulated within
1994 a Link State Update Packet. The Link State Update Packet should
1995 be sent directly to the neighbor. In so doing, do not put the
1996 database copy of the LSA on the neighbor's link state
1997 retransmission list, and do not acknowledge the received (less
1998 recent) LSA instance. */
1999 else
2000 {
2001 struct timeval now;
2002
Paul Jakma2518efd2006-08-27 06:49:29 +00002003 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00002004
2005 if (tv_cmp (tv_sub (now, current->tv_orig),
Paul Jakma2c9f8e32010-01-11 16:22:12 +00002006 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
paul718e3742002-12-13 20:15:29 +00002007 /* Trap NSSA type later.*/
2008 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2009 DISCARD_LSA (lsa, 8);
2010 }
2011 }
2012 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002013#undef DISCARD_LSA
2014
paul718e3742002-12-13 20:15:29 +00002015 assert (listcount (lsas) == 0);
2016 list_delete (lsas);
2017}
2018
2019/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002020static void
paul718e3742002-12-13 20:15:29 +00002021ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2022 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2023{
2024 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002025
paul718e3742002-12-13 20:15:29 +00002026 /* increment statistics. */
2027 oi->ls_ack_in++;
2028
pauld3f0d622004-05-05 15:27:15 +00002029 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002030 if (nbr == NULL)
2031 {
2032 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2033 inet_ntoa (ospfh->router_id));
2034 return;
2035 }
2036
Paul Jakma57c5c652010-01-07 06:12:53 +00002037 /* Add event to thread. */
2038 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2039
paul718e3742002-12-13 20:15:29 +00002040 if (nbr->state < NSM_Exchange)
2041 {
ajs3aa8d5f2004-12-11 18:00:06 +00002042 zlog_warn ("Link State Acknowledgment: "
2043 "Neighbor[%s] state %s is less than Exchange",
2044 inet_ntoa (ospfh->router_id),
2045 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002046 return;
2047 }
paul69310a62005-05-11 18:09:59 +00002048
paul718e3742002-12-13 20:15:29 +00002049 while (size >= OSPF_LSA_HEADER_SIZE)
2050 {
2051 struct ospf_lsa *lsa, *lsr;
2052
2053 lsa = ospf_lsa_new ();
2054 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2055
2056 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2057 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002058 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002059
2060 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2061 {
2062 lsa->data = NULL;
2063 ospf_lsa_discard (lsa);
2064 continue;
2065 }
2066
2067 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2068
2069 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2070 {
2071#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002072 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002073 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002074#endif /* HAVE_OPAQUE_LSA */
2075
2076 ospf_ls_retransmit_delete (nbr, lsr);
2077 }
2078
2079 lsa->data = NULL;
2080 ospf_lsa_discard (lsa);
2081 }
2082
paul718e3742002-12-13 20:15:29 +00002083 return;
paul718e3742002-12-13 20:15:29 +00002084}
2085
ajs038163f2005-02-17 19:55:59 +00002086static struct stream *
ajs5c333492005-02-23 15:43:01 +00002087ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002088{
2089 int ret;
ajs5c333492005-02-23 15:43:01 +00002090 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002091 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002092 unsigned int ifindex = 0;
2093 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002094 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002095 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002096 struct msghdr msgh;
2097
paul68defd62004-09-27 07:27:13 +00002098 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002099 msgh.msg_iov = &iov;
2100 msgh.msg_iovlen = 1;
2101 msgh.msg_control = (caddr_t) buff;
2102 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002103
ajs5c333492005-02-23 15:43:01 +00002104 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2105 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002106 {
ajs5c333492005-02-23 15:43:01 +00002107 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2108 return NULL;
2109 }
paul69310a62005-05-11 18:09:59 +00002110 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002111 {
2112 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2113 "(ip header size is %u)",
2114 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002115 return NULL;
2116 }
paul18b12c32004-10-05 14:38:29 +00002117
ajs5c333492005-02-23 15:43:01 +00002118 /* Note that there should not be alignment problems with this assignment
2119 because this is at the beginning of the stream data buffer. */
2120 iph = (struct ip *) STREAM_DATA(ibuf);
2121 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002122
ajs5c333492005-02-23 15:43:01 +00002123 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002124
Dmitrij Tejblumde5ccb92011-12-12 20:30:10 +04002125#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
paul718e3742002-12-13 20:15:29 +00002126 /*
2127 * Kernel network code touches incoming IP header parameters,
2128 * before protocol specific processing.
2129 *
2130 * 1) Convert byteorder to host representation.
2131 * --> ip_len, ip_id, ip_off
2132 *
2133 * 2) Adjust ip_len to strip IP header size!
2134 * --> If user process receives entire IP packet via RAW
2135 * socket, it must consider adding IP header size to
2136 * the "ip_len" field of "ip" structure.
2137 *
2138 * For more details, see <netinet/ip_input.c>.
2139 */
ajs5c333492005-02-23 15:43:01 +00002140 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002141#endif
2142
David BÉRARD0150c9c2010-05-11 10:17:53 +02002143#if defined(__DragonFly__)
2144 /*
2145 * in DragonFly's raw socket, ip_len/ip_off are read
2146 * in network byte order.
2147 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2148 */
2149 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2150#endif
2151
paul863082d2004-08-19 04:43:43 +00002152 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002153
2154 *ifp = if_lookup_by_index (ifindex);
2155
2156 if (ret != ip_len)
2157 {
ajs5c333492005-02-23 15:43:01 +00002158 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2159 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002160 return NULL;
2161 }
2162
2163 return ibuf;
2164}
2165
paul4dadc292005-05-06 21:37:42 +00002166static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002167ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002168 struct ip *iph, struct ospf_header *ospfh)
2169{
2170 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002171 struct ospf_vl_data *vl_data;
2172 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002173 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002174
2175 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2176 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002177 return NULL;
paul718e3742002-12-13 20:15:29 +00002178
pauld3f0d622004-05-05 15:27:15 +00002179 /* look for local OSPF interface matching the destination
2180 * to determine Area ID. We presume therefore the destination address
2181 * is unique, or at least (for "unnumbered" links), not used in other
2182 * areas
2183 */
2184 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2185 iph->ip_dst)) == NULL)
2186 return NULL;
paul718e3742002-12-13 20:15:29 +00002187
paul1eb8ef22005-04-07 07:30:20 +00002188 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002189 {
paul020709f2003-04-04 02:44:16 +00002190 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002191 if (!vl_area)
2192 continue;
2193
2194 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2195 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2196 {
2197 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002198 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002199 IF_NAME (vl_data->vl_oi));
2200 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2201 {
2202 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002203 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002204 return NULL;
2205 }
2206
2207 return vl_data->vl_oi;
2208 }
2209 }
2210
2211 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002212 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002213
pauld3f0d622004-05-05 15:27:15 +00002214 return NULL;
paul718e3742002-12-13 20:15:29 +00002215}
2216
Paul Jakmaf63f06d2011-04-08 12:44:43 +01002217static int
paul718e3742002-12-13 20:15:29 +00002218ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2219{
2220 /* Check match the Area ID of the receiving interface. */
2221 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2222 return 1;
2223
2224 return 0;
2225}
2226
2227/* Unbound socket will accept any Raw IP packets if proto is matched.
2228 To prevent it, compare src IP address and i/f address with masking
2229 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002230static int
paul718e3742002-12-13 20:15:29 +00002231ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2232{
2233 struct in_addr mask, me, him;
2234
2235 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2236 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2237 return 1;
2238
2239 masklen2ip (oi->address->prefixlen, &mask);
2240
2241 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2242 him.s_addr = ip_src.s_addr & mask.s_addr;
2243
2244 if (IPV4_ADDR_SAME (&me, &him))
2245 return 1;
2246
2247 return 0;
2248}
2249
paul4dadc292005-05-06 21:37:42 +00002250static int
paul718e3742002-12-13 20:15:29 +00002251ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2252 struct ospf_header *ospfh)
2253{
2254 int ret = 0;
2255 struct crypt_key *ck;
2256
2257 switch (ntohs (ospfh->auth_type))
2258 {
2259 case OSPF_AUTH_NULL:
2260 ret = 1;
2261 break;
2262 case OSPF_AUTH_SIMPLE:
2263 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2264 ret = 1;
2265 else
2266 ret = 0;
2267 break;
2268 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002269 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002270 {
2271 ret = 0;
2272 break;
2273 }
2274
2275 /* This is very basic, the digest processing is elsewhere */
2276 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2277 ospfh->u.crypt.key_id == ck->key_id &&
2278 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2279 ret = 1;
2280 else
2281 ret = 0;
2282 break;
2283 default:
2284 ret = 0;
2285 break;
2286 }
2287
2288 return ret;
2289}
2290
paul4dadc292005-05-06 21:37:42 +00002291static int
paul718e3742002-12-13 20:15:29 +00002292ospf_check_sum (struct ospf_header *ospfh)
2293{
2294 u_int32_t ret;
2295 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002296
2297 /* clear auth_data for checksum. */
2298 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2299
2300 /* keep checksum and clear. */
2301 sum = ospfh->checksum;
2302 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2303
2304 /* calculate checksum. */
2305 ret = in_cksum (ospfh, ntohs (ospfh->length));
2306
2307 if (ret != sum)
2308 {
2309 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2310 ret, sum);
2311 return 0;
2312 }
2313
2314 return 1;
2315}
2316
2317/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002318static int
paul718e3742002-12-13 20:15:29 +00002319ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2320 struct ip *iph, struct ospf_header *ospfh)
2321{
2322 /* check version. */
2323 if (ospfh->version != OSPF_VERSION)
2324 {
2325 zlog_warn ("interface %s: ospf_read version number mismatch.",
2326 IF_NAME (oi));
2327 return -1;
2328 }
2329
Denis Ovsienko71775042011-09-26 13:18:02 +04002330 /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
2331 if (ospfh->type < 1 || ospfh->type > 5)
2332 {
2333 zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
2334 return -1;
2335 }
2336
paul718e3742002-12-13 20:15:29 +00002337 /* Check Area ID. */
2338 if (!ospf_check_area_id (oi, ospfh))
2339 {
2340 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2341 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2342 return -1;
2343 }
2344
2345 /* Check network mask, Silently discarded. */
2346 if (! ospf_check_network_mask (oi, iph->ip_src))
2347 {
2348 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2349 IF_NAME (oi), inet_ntoa (iph->ip_src));
2350 return -1;
2351 }
2352
2353 /* Check authentication. */
2354 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2355 {
paulc6371712006-01-17 17:49:53 +00002356 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2357 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002358 return -1;
2359 }
2360
2361 if (! ospf_check_auth (oi, ibuf, ospfh))
2362 {
2363 zlog_warn ("interface %s: ospf_read authentication failed.",
2364 IF_NAME (oi));
2365 return -1;
2366 }
2367
2368 /* if check sum is invalid, packet is discarded. */
2369 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2370 {
2371 if (! ospf_check_sum (ospfh))
2372 {
2373 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2374 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2375 return -1;
2376 }
2377 }
2378 else
2379 {
2380 if (ospfh->checksum != 0)
2381 return -1;
2382 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2383 {
2384 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2385 IF_NAME (oi));
2386 return -1;
2387 }
2388 }
2389
2390 return 0;
2391}
2392
2393/* Starting point of packet process function. */
2394int
2395ospf_read (struct thread *thread)
2396{
2397 int ret;
2398 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002399 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002400 struct ospf_interface *oi;
2401 struct ip *iph;
2402 struct ospf_header *ospfh;
2403 u_int16_t length;
2404 struct interface *ifp;
2405
2406 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002407 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002408
2409 /* prepare for next packet. */
2410 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002411
2412 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002413 stream_reset(ospf->ibuf);
2414 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002415 return -1;
2416
ajs5c333492005-02-23 15:43:01 +00002417 /* Note that there should not be alignment problems with this assignment
2418 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002419 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002420 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002421
paulac191232004-10-22 12:05:17 +00002422 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002423 /* Handle cases where the platform does not support retrieving the ifindex,
2424 and also platforms (such as Solaris 8) that claim to support ifindex
2425 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002426 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002427
pauld3f0d622004-05-05 15:27:15 +00002428 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002429 return 0;
paul718e3742002-12-13 20:15:29 +00002430
2431 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002432 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002433 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002434
paul718e3742002-12-13 20:15:29 +00002435 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002436 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002437 {
pauld3241812003-09-29 12:42:39 +00002438 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2439 {
ajs2a42e282004-12-08 18:43:03 +00002440 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002441 inet_ntoa (iph->ip_src));
2442 }
paul718e3742002-12-13 20:15:29 +00002443 return 0;
2444 }
2445
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002446 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2447 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002448 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002449
2450 /* Make sure the OSPF header is really there. */
2451 if (stream_get_endp (ibuf) - stream_get_getp (ibuf) < OSPF_HEADER_SIZE)
2452 {
2453 zlog_debug ("ospf_read: ignored OSPF packet with undersized (%u bytes) header",
2454 stream_get_endp (ibuf) - stream_get_getp (ibuf));
2455 return -1;
2456 }
2457
2458 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002459 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2460
2461 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002462 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002463
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002464 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2465 after the passive/backbone/other checks below are passed. These checks
2466 in turn access the fields of unverified "ospfh" structure for their own
2467 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002468
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002469 /* If incoming interface is passive one, ignore it. */
2470 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2471 {
2472 char buf[3][INET_ADDRSTRLEN];
2473
2474 if (IS_DEBUG_OSPF_EVENT)
2475 zlog_debug ("ignoring packet from router %s sent to %s, "
2476 "received on a passive interface, %s",
2477 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2478 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2479 inet_ntop(AF_INET, &oi->address->u.prefix4,
2480 buf[2], sizeof(buf[2])));
2481
2482 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2483 {
2484 /* Try to fix multicast membership.
2485 * Some OS:es may have problems in this area,
2486 * make sure it is removed.
2487 */
2488 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2489 ospf_if_set_multicast(oi);
2490 }
2491 return 0;
2492 }
2493
2494
pauld3f0d622004-05-05 15:27:15 +00002495 /* if no local ospf_interface,
2496 * or header area is backbone but ospf_interface is not
2497 * check for VLINK interface
2498 */
2499 if ( (oi == NULL) ||
2500 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2501 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2502 )
2503 {
2504 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2505 {
Paul Jakma88871b12006-06-15 11:41:19 +00002506 if (IS_DEBUG_OSPF_EVENT)
2507 zlog_debug ("Packet from [%s] received on link %s"
2508 " but no ospf_interface",
2509 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002510 return 0;
2511 }
2512 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002513
pauld3f0d622004-05-05 15:27:15 +00002514 /* else it must be a local ospf interface, check it was received on
2515 * correct link
2516 */
2517 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002518 {
Paul Jakma11637432009-08-11 12:25:42 +01002519 if (IS_DEBUG_OSPF_EVENT)
2520 zlog_warn ("Packet from [%s] received on wrong link %s",
2521 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002522 return 0;
2523 }
ajs847947f2005-02-02 18:38:48 +00002524 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002525 {
ajsba6454e2005-02-08 15:37:30 +00002526 char buf[2][INET_ADDRSTRLEN];
2527 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002528 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002529 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2530 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2531 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002532 /* Fix multicast memberships? */
2533 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002534 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002535 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002536 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002537 if (oi->multicast_memberships)
2538 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002539 return 0;
2540 }
paul718e3742002-12-13 20:15:29 +00002541
2542 /*
2543 * If the received packet is destined for AllDRouters, the packet
2544 * should be accepted only if the received ospf interface state is
2545 * either DR or Backup -- endo.
2546 */
2547 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2548 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2549 {
ajsba6454e2005-02-08 15:37:30 +00002550 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002551 inet_ntoa (iph->ip_src), IF_NAME (oi),
2552 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002553 /* Try to fix multicast membership. */
2554 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2555 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002556 return 0;
2557 }
2558
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002559 /* Verify more OSPF header fields. */
2560 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2561 if (ret < 0)
2562 {
2563 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2564 zlog_debug ("ospf_read[%s]: Header check failed, "
2565 "dropping.",
2566 inet_ntoa (iph->ip_src));
2567 return ret;
2568 }
2569
paul718e3742002-12-13 20:15:29 +00002570 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002571 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2572 {
paul718e3742002-12-13 20:15:29 +00002573 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002574 {
ajs2a42e282004-12-08 18:43:03 +00002575 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002576 ospf_packet_dump (ibuf);
2577 }
paul718e3742002-12-13 20:15:29 +00002578
ajs2a42e282004-12-08 18:43:03 +00002579 zlog_debug ("%s received from [%s] via [%s]",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +04002580 LOOKUP (ospf_packet_type_str, ospfh->type),
paul1aa7b392003-04-08 08:51:58 +00002581 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002582 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2583 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002584
2585 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002586 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002587 }
paul718e3742002-12-13 20:15:29 +00002588
paul9985f832005-02-09 15:51:56 +00002589 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002590
2591 /* Adjust size to message length. */
2592 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2593
2594 /* Read rest of the packet and call each sort of packet routine. */
2595 switch (ospfh->type)
2596 {
2597 case OSPF_MSG_HELLO:
2598 ospf_hello (iph, ospfh, ibuf, oi, length);
2599 break;
2600 case OSPF_MSG_DB_DESC:
2601 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2602 break;
2603 case OSPF_MSG_LS_REQ:
2604 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2605 break;
2606 case OSPF_MSG_LS_UPD:
2607 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2608 break;
2609 case OSPF_MSG_LS_ACK:
2610 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2611 break;
2612 default:
2613 zlog (NULL, LOG_WARNING,
2614 "interface %s: OSPF packet header type %d is illegal",
2615 IF_NAME (oi), ospfh->type);
2616 break;
2617 }
2618
paul718e3742002-12-13 20:15:29 +00002619 return 0;
2620}
2621
2622/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002623static void
paul718e3742002-12-13 20:15:29 +00002624ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2625{
2626 struct ospf_header *ospfh;
2627
2628 ospfh = (struct ospf_header *) STREAM_DATA (s);
2629
2630 ospfh->version = (u_char) OSPF_VERSION;
2631 ospfh->type = (u_char) type;
2632
paul68980082003-03-25 05:07:42 +00002633 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002634
2635 ospfh->checksum = 0;
2636 ospfh->area_id = oi->area->area_id;
2637 ospfh->auth_type = htons (ospf_auth_type (oi));
2638
2639 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2640
paul9985f832005-02-09 15:51:56 +00002641 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002642}
2643
2644/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002645static int
paul718e3742002-12-13 20:15:29 +00002646ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2647{
2648 struct crypt_key *ck;
2649
2650 switch (ospf_auth_type (oi))
2651 {
2652 case OSPF_AUTH_NULL:
2653 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2654 break;
2655 case OSPF_AUTH_SIMPLE:
2656 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2657 OSPF_AUTH_SIMPLE_SIZE);
2658 break;
2659 case OSPF_AUTH_CRYPTOGRAPHIC:
2660 /* If key is not set, then set 0. */
2661 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2662 {
2663 ospfh->u.crypt.zero = 0;
2664 ospfh->u.crypt.key_id = 0;
2665 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2666 }
2667 else
2668 {
paul1eb8ef22005-04-07 07:30:20 +00002669 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002670 ospfh->u.crypt.zero = 0;
2671 ospfh->u.crypt.key_id = ck->key_id;
2672 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2673 }
2674 /* note: the seq is done in ospf_make_md5_digest() */
2675 break;
2676 default:
2677 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2678 break;
2679 }
2680
2681 return 0;
2682}
2683
2684/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002685static void
paul718e3742002-12-13 20:15:29 +00002686ospf_fill_header (struct ospf_interface *oi,
2687 struct stream *s, u_int16_t length)
2688{
2689 struct ospf_header *ospfh;
2690
2691 ospfh = (struct ospf_header *) STREAM_DATA (s);
2692
2693 /* Fill length. */
2694 ospfh->length = htons (length);
2695
2696 /* Calculate checksum. */
2697 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2698 ospfh->checksum = in_cksum (ospfh, length);
2699 else
2700 ospfh->checksum = 0;
2701
2702 /* Add Authentication Data. */
2703 ospf_make_auth (oi, ospfh);
2704}
2705
paul4dadc292005-05-06 21:37:42 +00002706static int
paul718e3742002-12-13 20:15:29 +00002707ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2708{
2709 struct ospf_neighbor *nbr;
2710 struct route_node *rn;
2711 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2712 struct in_addr mask;
2713 unsigned long p;
2714 int flag = 0;
2715
2716 /* Set netmask of interface. */
2717 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2718 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2719 masklen2ip (oi->address->prefixlen, &mask);
2720 else
2721 memset ((char *) &mask, 0, sizeof (struct in_addr));
2722 stream_put_ipv4 (s, mask.s_addr);
2723
2724 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002725 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2726 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2727 else
2728 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002729
2730 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002731 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002732 OPTIONS(oi), IF_NAME (oi));
2733
2734 /* Set Options. */
2735 stream_putc (s, OPTIONS (oi));
2736
2737 /* Set Router Priority. */
2738 stream_putc (s, PRIORITY (oi));
2739
2740 /* Set Router Dead Interval. */
2741 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2742
2743 /* Set Designated Router. */
2744 stream_put_ipv4 (s, DR (oi).s_addr);
2745
paul9985f832005-02-09 15:51:56 +00002746 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002747
2748 /* Set Backup Designated Router. */
2749 stream_put_ipv4 (s, BDR (oi).s_addr);
2750
2751 /* Add neighbor seen. */
2752 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002753 if ((nbr = rn->info))
2754 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2755 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2756 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2757 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002758 {
2759 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002760 if (nbr->d_router.s_addr != 0
2761 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2762 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2763 flag = 1;
paul718e3742002-12-13 20:15:29 +00002764
2765 stream_put_ipv4 (s, nbr->router_id.s_addr);
2766 length += 4;
2767 }
2768
2769 /* Let neighbor generate BackupSeen. */
2770 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002771 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002772
2773 return length;
2774}
2775
paul4dadc292005-05-06 21:37:42 +00002776static int
paul718e3742002-12-13 20:15:29 +00002777ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2778 struct stream *s)
2779{
2780 struct ospf_lsa *lsa;
2781 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2782 u_char options;
2783 unsigned long pp;
2784 int i;
2785 struct ospf_lsdb *lsdb;
2786
2787 /* Set Interface MTU. */
2788 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2789 stream_putw (s, 0);
2790 else
2791 stream_putw (s, oi->ifp->mtu);
2792
2793 /* Set Options. */
2794 options = OPTIONS (oi);
2795#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002796 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002797 {
2798 if (IS_SET_DD_I (nbr->dd_flags)
2799 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2800 /*
2801 * Set O-bit in the outgoing DD packet for capablity negotiation,
2802 * if one of following case is applicable.
2803 *
2804 * 1) WaitTimer expiration event triggered the neighbor state to
2805 * change to Exstart, but no (valid) DD packet has received
2806 * from the neighbor yet.
2807 *
2808 * 2) At least one DD packet with O-bit on has received from the
2809 * neighbor.
2810 */
2811 SET_FLAG (options, OSPF_OPTION_O);
2812 }
2813#endif /* HAVE_OPAQUE_LSA */
2814 stream_putc (s, options);
2815
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002816 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002817 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002818 stream_putc (s, nbr->dd_flags);
2819
2820 /* Set DD Sequence Number. */
2821 stream_putl (s, nbr->dd_seqnum);
2822
Paul Jakmab5aeb442006-08-30 18:47:37 +00002823 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002824 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002825 goto empty;
paul718e3742002-12-13 20:15:29 +00002826
2827 /* Describe LSA Header from Database Summary List. */
2828 lsdb = &nbr->db_sum;
2829
2830 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2831 {
2832 struct route_table *table = lsdb->type[i].db;
2833 struct route_node *rn;
2834
2835 for (rn = route_top (table); rn; rn = route_next (rn))
2836 if ((lsa = rn->info) != NULL)
2837 {
2838#ifdef HAVE_OPAQUE_LSA
2839 if (IS_OPAQUE_LSA (lsa->data->type)
2840 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2841 {
2842 /* Suppress advertising opaque-informations. */
2843 /* Remove LSA from DB summary list. */
2844 ospf_lsdb_delete (lsdb, lsa);
2845 continue;
2846 }
2847#endif /* HAVE_OPAQUE_LSA */
2848
2849 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2850 {
2851 struct lsa_header *lsah;
2852 u_int16_t ls_age;
2853
2854 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002855 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002856 break;
2857
2858 /* Keep pointer to LS age. */
2859 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002860 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002861
2862 /* Proceed stream pointer. */
2863 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2864 length += OSPF_LSA_HEADER_SIZE;
2865
2866 /* Set LS age. */
2867 ls_age = LS_AGE (lsa);
2868 lsah->ls_age = htons (ls_age);
2869
2870 }
2871
2872 /* Remove LSA from DB summary list. */
2873 ospf_lsdb_delete (lsdb, lsa);
2874 }
2875 }
2876
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002877 /* Update 'More' bit */
2878 if (ospf_db_summary_isempty (nbr))
2879 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002880empty:
2881 if (nbr->state >= NSM_Exchange)
2882 {
2883 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2884 /* Rewrite DD flags */
2885 stream_putc_at (s, pp, nbr->dd_flags);
2886 }
2887 else
2888 {
2889 assert (IS_SET_DD_M(nbr->dd_flags));
2890 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002891 }
paul718e3742002-12-13 20:15:29 +00002892 return length;
2893}
2894
paul4dadc292005-05-06 21:37:42 +00002895static int
paul718e3742002-12-13 20:15:29 +00002896ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2897 unsigned long delta, struct ospf_neighbor *nbr,
2898 struct ospf_lsa *lsa)
2899{
2900 struct ospf_interface *oi;
2901
2902 oi = nbr->oi;
2903
2904 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002905 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002906 return 0;
2907
2908 stream_putl (s, lsa->data->type);
2909 stream_put_ipv4 (s, lsa->data->id.s_addr);
2910 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2911
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002912 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002913 nbr->ls_req_last = ospf_lsa_lock (lsa);
2914
2915 *length += 12;
2916 return 1;
2917}
2918
paul4dadc292005-05-06 21:37:42 +00002919static int
paul718e3742002-12-13 20:15:29 +00002920ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2921{
2922 struct ospf_lsa *lsa;
2923 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002924 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002925 struct route_table *table;
2926 struct route_node *rn;
2927 int i;
2928 struct ospf_lsdb *lsdb;
2929
2930 lsdb = &nbr->ls_req;
2931
2932 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2933 {
2934 table = lsdb->type[i].db;
2935 for (rn = route_top (table); rn; rn = route_next (rn))
2936 if ((lsa = (rn->info)) != NULL)
2937 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2938 {
2939 route_unlock_node (rn);
2940 break;
2941 }
2942 }
2943 return length;
2944}
2945
paul4dadc292005-05-06 21:37:42 +00002946static int
paul718e3742002-12-13 20:15:29 +00002947ls_age_increment (struct ospf_lsa *lsa, int delay)
2948{
2949 int age;
2950
2951 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2952
2953 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2954}
2955
paul4dadc292005-05-06 21:37:42 +00002956static int
hasso52dc7ee2004-09-23 19:18:23 +00002957ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002958{
2959 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002960 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002961 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00002962 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002963 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002964 unsigned long pp;
2965 int count = 0;
2966
2967 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002968 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002969
paul9985f832005-02-09 15:51:56 +00002970 pp = stream_get_endp (s);
2971 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002972 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00002973
gdt86f1fd92005-01-10 14:20:43 +00002974 /* Calculate amount of packet usable for data. */
2975 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2976
paul718e3742002-12-13 20:15:29 +00002977 while ((node = listhead (update)) != NULL)
2978 {
2979 struct lsa_header *lsah;
2980 u_int16_t ls_age;
2981
2982 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002983 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002984
paul1eb8ef22005-04-07 07:30:20 +00002985 lsa = listgetdata (node);
2986
paul718e3742002-12-13 20:15:29 +00002987 assert (lsa->data);
2988
paul68b73392004-09-12 14:21:37 +00002989 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002990 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002991 break;
2992
paul718e3742002-12-13 20:15:29 +00002993 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002994 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002995
2996 /* Put LSA to Link State Request. */
2997 stream_put (s, lsa->data, ntohs (lsa->data->length));
2998
2999 /* Set LS age. */
3000 /* each hop must increment an lsa_age by transmit_delay
3001 of OSPF interface */
3002 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3003 lsah->ls_age = htons (ls_age);
3004
3005 length += ntohs (lsa->data->length);
3006 count++;
3007
3008 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003009 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003010 }
3011
3012 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003013 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003014
3015 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003016 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003017 return length;
3018}
3019
paul4dadc292005-05-06 21:37:42 +00003020static int
hasso52dc7ee2004-09-23 19:18:23 +00003021ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003022{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003023 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003024 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003025 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003026 struct ospf_lsa *lsa;
3027
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003028 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003029 {
paul718e3742002-12-13 20:15:29 +00003030 assert (lsa);
3031
gdt86f1fd92005-01-10 14:20:43 +00003032 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003033 break;
3034
3035 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3036 length += OSPF_LSA_HEADER_SIZE;
3037
paul718e3742002-12-13 20:15:29 +00003038 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003039 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003040 }
3041
paul718e3742002-12-13 20:15:29 +00003042 return length;
3043}
3044
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003045static void
3046ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003047{
3048 struct ospf_packet *op;
3049 u_int16_t length = OSPF_HEADER_SIZE;
3050
3051 op = ospf_packet_new (oi->ifp->mtu);
3052
3053 /* Prepare OSPF common header. */
3054 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3055
3056 /* Prepare OSPF Hello body. */
3057 length += ospf_make_hello (oi, op->s);
3058
3059 /* Fill OSPF header. */
3060 ospf_fill_header (oi, op->s, length);
3061
3062 /* Set packet length. */
3063 op->length = length;
3064
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003065 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003066
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003067 /* Add packet to the top of the interface output queue, so that they
3068 * can't get delayed by things like long queues of LS Update packets
3069 */
3070 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003071
3072 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003073 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003074}
3075
paul4dadc292005-05-06 21:37:42 +00003076static void
paul718e3742002-12-13 20:15:29 +00003077ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3078{
3079 struct ospf_interface *oi;
3080
3081 oi = nbr_nbma->oi;
3082 assert(oi);
3083
3084 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003085 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003086 return;
3087
3088 if (oi->type != OSPF_IFTYPE_NBMA)
3089 return;
3090
3091 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3092 return;
3093
3094 if (PRIORITY(oi) == 0)
3095 return;
3096
3097 if (nbr_nbma->priority == 0
3098 && oi->state != ISM_DR && oi->state != ISM_Backup)
3099 return;
3100
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003101 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003102}
3103
3104int
3105ospf_poll_timer (struct thread *thread)
3106{
3107 struct ospf_nbr_nbma *nbr_nbma;
3108
3109 nbr_nbma = THREAD_ARG (thread);
3110 nbr_nbma->t_poll = NULL;
3111
3112 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003113 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003114 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3115
3116 ospf_poll_send (nbr_nbma);
3117
3118 if (nbr_nbma->v_poll > 0)
3119 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3120 nbr_nbma->v_poll);
3121
3122 return 0;
3123}
3124
3125
3126int
3127ospf_hello_reply_timer (struct thread *thread)
3128{
3129 struct ospf_neighbor *nbr;
3130
3131 nbr = THREAD_ARG (thread);
3132 nbr->t_hello_reply = NULL;
3133
3134 assert (nbr->oi);
3135
3136 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003137 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003138 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3139
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003140 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003141
3142 return 0;
3143}
3144
3145/* Send OSPF Hello. */
3146void
3147ospf_hello_send (struct ospf_interface *oi)
3148{
paul718e3742002-12-13 20:15:29 +00003149 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003150 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003151 return;
3152
paul718e3742002-12-13 20:15:29 +00003153 if (oi->type == OSPF_IFTYPE_NBMA)
3154 {
3155 struct ospf_neighbor *nbr;
3156 struct route_node *rn;
3157
3158 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3159 if ((nbr = rn->info))
3160 if (nbr != oi->nbr_self)
3161 if (nbr->state != NSM_Down)
3162 {
3163 /* RFC 2328 Section 9.5.1
3164 If the router is not eligible to become Designated Router,
3165 it must periodically send Hello Packets to both the
3166 Designated Router and the Backup Designated Router (if they
3167 exist). */
3168 if (PRIORITY(oi) == 0 &&
3169 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3170 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3171 continue;
3172
3173 /* If the router is eligible to become Designated Router, it
3174 must periodically send Hello Packets to all neighbors that
3175 are also eligible. In addition, if the router is itself the
3176 Designated Router or Backup Designated Router, it must also
3177 send periodic Hello Packets to all other neighbors. */
3178
3179 if (nbr->priority == 0 && oi->state == ISM_DROther)
3180 continue;
3181 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003182 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003183 }
paul718e3742002-12-13 20:15:29 +00003184 }
3185 else
3186 {
3187 /* Decide destination address. */
3188 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003189 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3190 else
3191 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003192 }
3193}
3194
3195/* Send OSPF Database Description. */
3196void
3197ospf_db_desc_send (struct ospf_neighbor *nbr)
3198{
3199 struct ospf_interface *oi;
3200 struct ospf_packet *op;
3201 u_int16_t length = OSPF_HEADER_SIZE;
3202
3203 oi = nbr->oi;
3204 op = ospf_packet_new (oi->ifp->mtu);
3205
3206 /* Prepare OSPF common header. */
3207 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3208
3209 /* Prepare OSPF Database Description body. */
3210 length += ospf_make_db_desc (oi, nbr, op->s);
3211
3212 /* Fill OSPF header. */
3213 ospf_fill_header (oi, op->s, length);
3214
3215 /* Set packet length. */
3216 op->length = length;
3217
3218 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003219 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3220 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3221 else
3222 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003223
3224 /* Add packet to the interface output queue. */
3225 ospf_packet_add (oi, op);
3226
3227 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003228 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003229
3230 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3231 if (nbr->last_send)
3232 ospf_packet_free (nbr->last_send);
3233 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003234 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003235}
3236
3237/* Re-send Database Description. */
3238void
3239ospf_db_desc_resend (struct ospf_neighbor *nbr)
3240{
3241 struct ospf_interface *oi;
3242
3243 oi = nbr->oi;
3244
3245 /* Add packet to the interface output queue. */
3246 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3247
3248 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003249 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003250}
3251
3252/* Send Link State Request. */
3253void
3254ospf_ls_req_send (struct ospf_neighbor *nbr)
3255{
3256 struct ospf_interface *oi;
3257 struct ospf_packet *op;
3258 u_int16_t length = OSPF_HEADER_SIZE;
3259
3260 oi = nbr->oi;
3261 op = ospf_packet_new (oi->ifp->mtu);
3262
3263 /* Prepare OSPF common header. */
3264 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3265
3266 /* Prepare OSPF Link State Request body. */
3267 length += ospf_make_ls_req (nbr, op->s);
3268 if (length == OSPF_HEADER_SIZE)
3269 {
3270 ospf_packet_free (op);
3271 return;
3272 }
3273
3274 /* Fill OSPF header. */
3275 ospf_fill_header (oi, op->s, length);
3276
3277 /* Set packet length. */
3278 op->length = length;
3279
3280 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003281 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3282 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3283 else
3284 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003285
3286 /* Add packet to the interface output queue. */
3287 ospf_packet_add (oi, op);
3288
3289 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003290 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003291
3292 /* Add Link State Request Retransmission Timer. */
3293 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3294}
3295
3296/* Send Link State Update with an LSA. */
3297void
3298ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3299 int flag)
3300{
hasso52dc7ee2004-09-23 19:18:23 +00003301 struct list *update;
paul718e3742002-12-13 20:15:29 +00003302
3303 update = list_new ();
3304
3305 listnode_add (update, lsa);
3306 ospf_ls_upd_send (nbr, update, flag);
3307
3308 list_delete (update);
3309}
3310
paul68b73392004-09-12 14:21:37 +00003311/* Determine size for packet. Must be at least big enough to accomodate next
3312 * LSA on list, which may be bigger than MTU size.
3313 *
3314 * Return pointer to new ospf_packet
3315 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3316 * on packet sizes (in which case offending LSA is deleted from update list)
3317 */
3318static struct ospf_packet *
3319ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3320{
3321 struct ospf_lsa *lsa;
3322 struct listnode *ln;
3323 size_t size;
3324 static char warned = 0;
3325
paul1eb8ef22005-04-07 07:30:20 +00003326 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003327 assert (lsa->data);
3328
3329 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3330 > ospf_packet_max (oi))
3331 {
3332 if (!warned)
3333 {
3334 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3335 "will need to fragment. Not optimal. Try divide up"
3336 " your network with areas. Use 'debug ospf packet send'"
3337 " to see details, or look at 'show ip ospf database ..'");
3338 warned = 1;
3339 }
3340
3341 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003342 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003343 " %d bytes originated by %s, will be fragmented!",
3344 inet_ntoa (lsa->data->id),
3345 ntohs (lsa->data->length),
3346 inet_ntoa (lsa->data->adv_router));
3347
3348 /*
3349 * Allocate just enough to fit this LSA only, to avoid including other
3350 * LSAs in fragmented LSA Updates.
3351 */
3352 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3353 + OSPF_LS_UPD_MIN_SIZE;
3354 }
3355 else
3356 size = oi->ifp->mtu;
3357
3358 if (size > OSPF_MAX_PACKET_SIZE)
3359 {
3360 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003361 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003362 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003363 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003364 (long int) size);
paul68b73392004-09-12 14:21:37 +00003365 list_delete_node (update, ln);
3366 return NULL;
3367 }
3368
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003369 /* IP header is built up separately by ospf_write(). This means, that we must
3370 * reduce the "affordable" size just calculated by length of an IP header.
3371 * This makes sure, that even if we manage to fill the payload with LSA data
3372 * completely, the final packet (our data plus IP header) still fits into
3373 * outgoing interface MTU. This correction isn't really meaningful for an
3374 * oversized LSA, but for consistency the correction is done for both cases.
3375 *
3376 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3377 */
3378 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003379}
3380
paul718e3742002-12-13 20:15:29 +00003381static void
hasso52dc7ee2004-09-23 19:18:23 +00003382ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003383 struct in_addr addr)
3384{
3385 struct ospf_packet *op;
3386 u_int16_t length = OSPF_HEADER_SIZE;
3387
3388 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003389 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003390
3391 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003392
3393 /* Prepare OSPF common header. */
3394 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3395
paul59ea14c2004-07-14 20:50:36 +00003396 /* Prepare OSPF Link State Update body.
3397 * Includes Type-7 translation.
3398 */
paul718e3742002-12-13 20:15:29 +00003399 length += ospf_make_ls_upd (oi, update, op->s);
3400
3401 /* Fill OSPF header. */
3402 ospf_fill_header (oi, op->s, length);
3403
3404 /* Set packet length. */
3405 op->length = length;
3406
3407 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003408 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3409 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3410 else
3411 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003412
3413 /* Add packet to the interface output queue. */
3414 ospf_packet_add (oi, op);
3415
3416 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003417 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003418}
3419
3420static int
3421ospf_ls_upd_send_queue_event (struct thread *thread)
3422{
3423 struct ospf_interface *oi = THREAD_ARG(thread);
3424 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003425 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003426 struct list *update;
paul68b73392004-09-12 14:21:37 +00003427 char again = 0;
paul718e3742002-12-13 20:15:29 +00003428
3429 oi->t_ls_upd_event = NULL;
3430
3431 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003432 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003433
paul736d3442003-07-24 23:22:57 +00003434 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003435 {
paul736d3442003-07-24 23:22:57 +00003436 rnext = route_next (rn);
3437
paul718e3742002-12-13 20:15:29 +00003438 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003439 continue;
paul68b73392004-09-12 14:21:37 +00003440
3441 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003442
paul48fe13b2004-07-27 17:40:44 +00003443 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003444
paul68b73392004-09-12 14:21:37 +00003445 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003446 if (listcount(update) == 0)
3447 {
3448 list_delete (rn->info);
3449 rn->info = NULL;
3450 route_unlock_node (rn);
3451 }
3452 else
paul68b73392004-09-12 14:21:37 +00003453 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003454 }
3455
3456 if (again != 0)
3457 {
3458 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003459 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003460 " %d nodes to try again, raising new event", again);
3461 oi->t_ls_upd_event =
3462 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003463 }
3464
3465 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003466 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003467
paul718e3742002-12-13 20:15:29 +00003468 return 0;
3469}
3470
3471void
hasso52dc7ee2004-09-23 19:18:23 +00003472ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003473{
3474 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003475 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003476 struct prefix_ipv4 p;
3477 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003478 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003479
3480 oi = nbr->oi;
3481
3482 p.family = AF_INET;
3483 p.prefixlen = IPV4_MAX_BITLEN;
3484
3485 /* Decide destination address. */
3486 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3487 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003488 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3489 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003490 else if (flag == OSPF_SEND_PACKET_DIRECT)
3491 p.prefix = nbr->address.u.prefix4;
3492 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3493 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003494 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3495 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003496 else
3497 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3498
3499 if (oi->type == OSPF_IFTYPE_NBMA)
3500 {
3501 if (flag == OSPF_SEND_PACKET_INDIRECT)
3502 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3503 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3504 zlog_warn ("* LS-Update is sent to myself.");
3505 }
3506
3507 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3508
3509 if (rn->info == NULL)
3510 rn->info = list_new ();
3511
paul1eb8ef22005-04-07 07:30:20 +00003512 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003513 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003514
3515 if (oi->t_ls_upd_event == NULL)
3516 oi->t_ls_upd_event =
3517 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3518}
3519
3520static void
hasso52dc7ee2004-09-23 19:18:23 +00003521ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3522 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003523{
3524 struct ospf_packet *op;
3525 u_int16_t length = OSPF_HEADER_SIZE;
3526
3527 op = ospf_packet_new (oi->ifp->mtu);
3528
3529 /* Prepare OSPF common header. */
3530 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3531
3532 /* Prepare OSPF Link State Acknowledgment body. */
3533 length += ospf_make_ls_ack (oi, ack, op->s);
3534
3535 /* Fill OSPF header. */
3536 ospf_fill_header (oi, op->s, length);
3537
3538 /* Set packet length. */
3539 op->length = length;
3540
3541 /* Set destination IP address. */
3542 op->dst = dst;
3543
3544 /* Add packet to the interface output queue. */
3545 ospf_packet_add (oi, op);
3546
3547 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003548 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003549}
3550
3551static int
3552ospf_ls_ack_send_event (struct thread *thread)
3553{
3554 struct ospf_interface *oi = THREAD_ARG (thread);
3555
3556 oi->t_ls_ack_direct = NULL;
3557
3558 while (listcount (oi->ls_ack_direct.ls_ack))
3559 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3560 oi->ls_ack_direct.dst);
3561
3562 return 0;
3563}
3564
3565void
3566ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3567{
3568 struct ospf_interface *oi = nbr->oi;
3569
3570 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3571 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3572
3573 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3574
3575 if (oi->t_ls_ack_direct == NULL)
3576 oi->t_ls_ack_direct =
3577 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3578}
3579
3580/* Send Link State Acknowledgment delayed. */
3581void
3582ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3583{
3584 struct in_addr dst;
3585
3586 /* Decide destination address. */
3587 /* RFC2328 Section 13.5 On non-broadcast
3588 networks, delayed Link State Acknowledgment packets must be
3589 unicast separately over each adjacency (i.e., neighbor whose
3590 state is >= Exchange). */
3591 if (oi->type == OSPF_IFTYPE_NBMA)
3592 {
3593 struct ospf_neighbor *nbr;
3594 struct route_node *rn;
3595
3596 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3597 if ((nbr = rn->info) != NULL)
3598 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3599 while (listcount (oi->ls_ack))
3600 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3601 return;
3602 }
3603 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3604 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3605 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3606 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3607 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3608 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003609 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3610 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003611 else
3612 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3613
3614 while (listcount (oi->ls_ack))
3615 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3616}