blob: 0f338d35587028cc292c18777c4eb5ce363f6327 [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. */
hassoeb1ce602004-10-08 08:17:22 +000053const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000054{
55 "unknown",
56 "Hello",
57 "Database Description",
58 "Link State Request",
59 "Link State Update",
60 "Link State Acknowledgment",
61};
62
paul718e3742002-12-13 20:15:29 +000063/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000064static int
paul718e3742002-12-13 20:15:29 +000065ospf_auth_type (struct ospf_interface *oi)
66{
67 int auth_type;
68
69 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
70 auth_type = oi->area->auth_type;
71 else
72 auth_type = OSPF_IF_PARAM (oi, auth_type);
73
74 /* Handle case where MD5 key list is not configured aka Cisco */
75 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
76 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
77 return OSPF_AUTH_NULL;
78
79 return auth_type;
80
81}
82
paul718e3742002-12-13 20:15:29 +000083struct ospf_packet *
84ospf_packet_new (size_t size)
85{
86 struct ospf_packet *new;
87
88 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
89 new->s = stream_new (size);
90
91 return new;
92}
93
94void
95ospf_packet_free (struct ospf_packet *op)
96{
97 if (op->s)
98 stream_free (op->s);
99
100 XFREE (MTYPE_OSPF_PACKET, op);
101
102 op = NULL;
103}
104
105struct ospf_fifo *
106ospf_fifo_new ()
107{
108 struct ospf_fifo *new;
109
110 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
111 return new;
112}
113
114/* Add new packet to fifo. */
115void
116ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
117{
118 if (fifo->tail)
119 fifo->tail->next = op;
120 else
121 fifo->head = op;
122
123 fifo->tail = op;
124
125 fifo->count++;
126}
127
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000128/* Add new packet to head of fifo. */
129static void
130ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
131{
132 op->next = fifo->head;
133
134 if (fifo->tail == NULL)
135 fifo->tail = op;
136
137 fifo->head = op;
138
139 fifo->count++;
140}
141
paul718e3742002-12-13 20:15:29 +0000142/* Delete first packet from fifo. */
143struct ospf_packet *
144ospf_fifo_pop (struct ospf_fifo *fifo)
145{
146 struct ospf_packet *op;
147
148 op = fifo->head;
149
150 if (op)
151 {
152 fifo->head = op->next;
153
154 if (fifo->head == NULL)
155 fifo->tail = NULL;
156
157 fifo->count--;
158 }
159
160 return op;
161}
162
163/* Return first fifo entry. */
164struct ospf_packet *
165ospf_fifo_head (struct ospf_fifo *fifo)
166{
167 return fifo->head;
168}
169
170/* Flush ospf packet fifo. */
171void
172ospf_fifo_flush (struct ospf_fifo *fifo)
173{
174 struct ospf_packet *op;
175 struct ospf_packet *next;
176
177 for (op = fifo->head; op; op = next)
178 {
179 next = op->next;
180 ospf_packet_free (op);
181 }
182 fifo->head = fifo->tail = NULL;
183 fifo->count = 0;
184}
185
186/* Free ospf packet fifo. */
187void
188ospf_fifo_free (struct ospf_fifo *fifo)
189{
190 ospf_fifo_flush (fifo);
191
192 XFREE (MTYPE_OSPF_FIFO, fifo);
193}
194
195void
196ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
197{
ajsc3eab872005-01-29 15:52:07 +0000198 if (!oi->obuf)
199 {
200 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
201 "destination %s) called with NULL obuf, ignoring "
202 "(please report this bug)!\n",
203 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
204 ospf_packet_type_str[stream_getc_from(op->s, 1)],
205 inet_ntoa (op->dst));
206 return;
207 }
208
paul718e3742002-12-13 20:15:29 +0000209 /* Add packet to end of queue. */
210 ospf_fifo_push (oi->obuf, op);
211
212 /* Debug of packet fifo*/
213 /* ospf_fifo_debug (oi->obuf); */
214}
215
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000216static void
217ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
218{
219 if (!oi->obuf)
220 {
221 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
222 "destination %s) called with NULL obuf, ignoring "
223 "(please report this bug)!\n",
224 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
225 ospf_packet_type_str[stream_getc_from(op->s, 1)],
226 inet_ntoa (op->dst));
227 return;
228 }
229
230 /* Add packet to head of queue. */
231 ospf_fifo_push_head (oi->obuf, op);
232
233 /* Debug of packet fifo*/
234 /* ospf_fifo_debug (oi->obuf); */
235}
236
paul718e3742002-12-13 20:15:29 +0000237void
238ospf_packet_delete (struct ospf_interface *oi)
239{
240 struct ospf_packet *op;
241
242 op = ospf_fifo_pop (oi->obuf);
243
244 if (op)
245 ospf_packet_free (op);
246}
247
paul718e3742002-12-13 20:15:29 +0000248struct ospf_packet *
249ospf_packet_dup (struct ospf_packet *op)
250{
251 struct ospf_packet *new;
252
paul37163d62003-02-03 18:40:56 +0000253 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000254 /* XXX size_t */
255 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
256 (u_long)STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000257
258 /* Reserve space for MD5 authentication that may be added later. */
259 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000260 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000261
262 new->dst = op->dst;
263 new->length = op->length;
264
265 return new;
266}
267
gdt86f1fd92005-01-10 14:20:43 +0000268/* XXX inline */
paul4dadc292005-05-06 21:37:42 +0000269static inline unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000270ospf_packet_authspace (struct ospf_interface *oi)
271{
272 int auth = 0;
273
274 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
275 auth = OSPF_AUTH_MD5_SIZE;
276
277 return auth;
278}
279
paul4dadc292005-05-06 21:37:42 +0000280static unsigned int
paul718e3742002-12-13 20:15:29 +0000281ospf_packet_max (struct ospf_interface *oi)
282{
283 int max;
284
gdt86f1fd92005-01-10 14:20:43 +0000285 max = oi->ifp->mtu - ospf_packet_authspace(oi);
286
paul68b73392004-09-12 14:21:37 +0000287 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000288
289 return max;
290}
291
292
paul4dadc292005-05-06 21:37:42 +0000293static int
paul718e3742002-12-13 20:15:29 +0000294ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
295 u_int16_t length)
296{
paul6c835672004-10-11 11:00:30 +0000297 unsigned char *ibuf;
vincentc1a03d42005-09-28 15:47:44 +0000298 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000299 unsigned char digest[OSPF_AUTH_MD5_SIZE];
300 unsigned char *pdigest;
301 struct crypt_key *ck;
302 struct ospf_header *ospfh;
303 struct ospf_neighbor *nbr;
304
305
306 ibuf = STREAM_PNT (s);
307 ospfh = (struct ospf_header *) ibuf;
308
309 /* Get pointer to the end of the packet. */
310 pdigest = ibuf + length;
311
312 /* Get secret key. */
313 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
314 ospfh->u.crypt.key_id);
315 if (ck == NULL)
316 {
317 zlog_warn ("interface %s: ospf_check_md5 no key %d",
318 IF_NAME (oi), ospfh->u.crypt.key_id);
319 return 0;
320 }
321
322 /* check crypto seqnum. */
323 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
324
325 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
326 {
327 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
328 IF_NAME (oi),
329 ntohl(ospfh->u.crypt.crypt_seqnum),
330 ntohl(nbr->crypt_seqnum));
331 return 0;
332 }
333
334 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000335 memset(&ctx, 0, sizeof(ctx));
336 MD5Init(&ctx);
337 MD5Update(&ctx, ibuf, length);
338 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
339 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000340
341 /* compare the two */
342 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
343 {
344 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
345 IF_NAME (oi));
346 return 0;
347 }
348
349 /* save neighbor's crypt_seqnum */
350 if (nbr)
351 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
352 return 1;
353}
354
355/* This function is called from ospf_write(), it will detect the
356 authentication scheme and if it is MD5, it will change the sequence
357 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000358static int
paul718e3742002-12-13 20:15:29 +0000359ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
360{
361 struct ospf_header *ospfh;
362 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000363 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000364 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000365 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000366 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000367 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000368
369 ibuf = STREAM_DATA (op->s);
370 ospfh = (struct ospf_header *) ibuf;
371
372 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
373 return 0;
374
375 /* We do this here so when we dup a packet, we don't have to
Paul Jakma2518efd2006-08-27 06:49:29 +0000376 waste CPU rewriting other headers.
377
378 Note that quagga_time /deliberately/ is not used here */
paul9483e152002-12-13 20:55:25 +0000379 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000380 if (t > oi->crypt_seqnum)
381 oi->crypt_seqnum = t;
382 else
383 oi->crypt_seqnum++;
384
paul9483e152002-12-13 20:55:25 +0000385 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000386
387 /* Get MD5 Authentication key from auth_key list. */
388 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000389 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000390 else
391 {
paul1eb8ef22005-04-07 07:30:20 +0000392 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000393 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000394 }
395
396 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000397 memset(&ctx, 0, sizeof(ctx));
398 MD5Init(&ctx);
399 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
400 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
401 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000402
403 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000404 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000405
406 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000407 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
408
paul37163d62003-02-03 18:40:56 +0000409 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000410 /* XXX size_t */
411 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
412 (u_long)stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000413
414 return OSPF_AUTH_MD5_SIZE;
415}
416
417
paul4dadc292005-05-06 21:37:42 +0000418static int
paul718e3742002-12-13 20:15:29 +0000419ospf_ls_req_timer (struct thread *thread)
420{
421 struct ospf_neighbor *nbr;
422
423 nbr = THREAD_ARG (thread);
424 nbr->t_ls_req = NULL;
425
426 /* Send Link State Request. */
427 if (ospf_ls_request_count (nbr))
428 ospf_ls_req_send (nbr);
429
430 /* Set Link State Request retransmission timer. */
431 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
432
433 return 0;
434}
435
436void
437ospf_ls_req_event (struct ospf_neighbor *nbr)
438{
439 if (nbr->t_ls_req)
440 {
441 thread_cancel (nbr->t_ls_req);
442 nbr->t_ls_req = NULL;
443 }
444 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
445}
446
447/* Cyclic timer function. Fist registered in ospf_nbr_new () in
448 ospf_neighbor.c */
449int
450ospf_ls_upd_timer (struct thread *thread)
451{
452 struct ospf_neighbor *nbr;
453
454 nbr = THREAD_ARG (thread);
455 nbr->t_ls_upd = NULL;
456
457 /* Send Link State Update. */
458 if (ospf_ls_retransmit_count (nbr) > 0)
459 {
hasso52dc7ee2004-09-23 19:18:23 +0000460 struct list *update;
paul718e3742002-12-13 20:15:29 +0000461 struct ospf_lsdb *lsdb;
462 int i;
paul718e3742002-12-13 20:15:29 +0000463 int retransmit_interval;
464
paul718e3742002-12-13 20:15:29 +0000465 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
466
467 lsdb = &nbr->ls_rxmt;
468 update = list_new ();
469
470 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
471 {
472 struct route_table *table = lsdb->type[i].db;
473 struct route_node *rn;
474
475 for (rn = route_top (table); rn; rn = route_next (rn))
476 {
477 struct ospf_lsa *lsa;
478
479 if ((lsa = rn->info) != NULL)
480 /* Don't retransmit an LSA if we received it within
481 the last RxmtInterval seconds - this is to allow the
482 neighbour a chance to acknowledge the LSA as it may
483 have ben just received before the retransmit timer
484 fired. This is a small tweak to what is in the RFC,
485 but it will cut out out a lot of retransmit traffic
486 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000487 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000488 int2tv (retransmit_interval)) >= 0)
489 listnode_add (update, rn->info);
490 }
491 }
492
493 if (listcount (update) > 0)
494 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
495 list_delete (update);
496 }
497
498 /* Set LS Update retransmission timer. */
499 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
500
501 return 0;
502}
503
504int
505ospf_ls_ack_timer (struct thread *thread)
506{
507 struct ospf_interface *oi;
508
509 oi = THREAD_ARG (thread);
510 oi->t_ls_ack = NULL;
511
512 /* Send Link State Acknowledgment. */
513 if (listcount (oi->ls_ack) > 0)
514 ospf_ls_ack_send_delayed (oi);
515
516 /* Set LS Ack timer. */
517 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
518
519 return 0;
520}
521
paul0bfeca32004-09-24 08:07:54 +0000522#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000523static void
paul6a99f832004-09-27 12:56:30 +0000524ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000525 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000526 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000527{
528#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000529 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000530 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000531 int ret;
paul0bfeca32004-09-24 08:07:54 +0000532
533 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000534 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000535
536 /* we can but try.
537 *
538 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
539 * well as the IP_MF flag, making this all quite pointless.
540 *
541 * However, for a system on which IP_MF is left alone, and ip_id left
542 * alone or else which sets same ip_id for each fragment this might
543 * work, eg linux.
544 *
545 * XXX-TODO: It would be much nicer to have the kernel's use their
546 * existing fragmentation support to do this for us. Bugs/RFEs need to
547 * be raised against the various kernels.
548 */
549
550 /* set More Frag */
551 iph->ip_off |= IP_MF;
552
553 /* ip frag offset is expressed in units of 8byte words */
554 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
555
paul62d8e962004-11-02 20:26:45 +0000556 iovp = &msg->msg_iov[1];
557
paul0bfeca32004-09-24 08:07:54 +0000558 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
559 > maxdatasize )
560 {
561 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000562 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
563 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000564 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000565
paul18b12c32004-10-05 14:38:29 +0000566 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000567
paul6a99f832004-09-27 12:56:30 +0000568 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000569
paul18b12c32004-10-05 14:38:29 +0000570 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000571
572 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000573 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000574 " id %d, off %d, len %d, mtu %u failed with %s",
575 inet_ntoa (iph->ip_dst),
576 iph->ip_id,
577 iph->ip_off,
578 iph->ip_len,
579 mtu,
580 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000581
paul37ccfa32004-10-31 11:24:51 +0000582 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
583 {
ajs2a42e282004-12-08 18:43:03 +0000584 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000585 iph->ip_id, iph->ip_off, iph->ip_len,
586 inet_ntoa (iph->ip_dst));
587 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
588 {
ajs2a42e282004-12-08 18:43:03 +0000589 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000590 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000591 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000592 }
593 }
594
paul0bfeca32004-09-24 08:07:54 +0000595 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000596 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000597 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000598 }
599
600 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000601 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
602 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000603 iph->ip_off &= (~IP_MF);
604}
605#endif /* WANT_OSPF_WRITE_FRAGMENT */
606
ajs5dcbdf82005-03-29 16:13:49 +0000607static int
paul718e3742002-12-13 20:15:29 +0000608ospf_write (struct thread *thread)
609{
paul68980082003-03-25 05:07:42 +0000610 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000611 struct ospf_interface *oi;
612 struct ospf_packet *op;
613 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000614 struct ip iph;
615 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000616 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000617 u_char type;
618 int ret;
619 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000620 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000621#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000622 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000623#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000624 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000625#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000626
paul68980082003-03-25 05:07:42 +0000627 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000628
paul68980082003-03-25 05:07:42 +0000629 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000630 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000631 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000632 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000633
634#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000635 /* seed ipid static with low order bits of time */
636 if (ipid == 0)
637 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000638#endif /* WANT_OSPF_WRITE_FRAGMENT */
639
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000640 /* convenience - max OSPF data per packet,
641 * and reliability - not more data, than our
642 * socket can accept
643 */
644 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
645 sizeof (struct ip);
paul68b73392004-09-12 14:21:37 +0000646
paul718e3742002-12-13 20:15:29 +0000647 /* Get one packet from queue. */
648 op = ospf_fifo_head (oi->obuf);
649 assert (op);
650 assert (op->length >= OSPF_HEADER_SIZE);
651
paul68980082003-03-25 05:07:42 +0000652 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
653 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000654 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
655
paul718e3742002-12-13 20:15:29 +0000656 /* Rewrite the md5 signature & update the seq */
657 ospf_make_md5_digest (oi, op);
658
paul37ccfa32004-10-31 11:24:51 +0000659 /* Retrieve OSPF packet type. */
660 stream_set_getp (op->s, 1);
661 type = stream_getc (op->s);
662
paul68b73392004-09-12 14:21:37 +0000663 /* reset get pointer */
664 stream_set_getp (op->s, 0);
665
666 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000667 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000668
paul718e3742002-12-13 20:15:29 +0000669 sa_dst.sin_family = AF_INET;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000670#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +0000671 sa_dst.sin_len = sizeof(sa_dst);
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000672#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +0000673 sa_dst.sin_addr = op->dst;
674 sa_dst.sin_port = htons (0);
675
676 /* Set DONTROUTE flag if dst is unicast. */
677 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
678 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
679 flags = MSG_DONTROUTE;
680
paul68b73392004-09-12 14:21:37 +0000681 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
682 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000683 if ( sizeof (struct ip)
684 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000685 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
686
paul718e3742002-12-13 20:15:29 +0000687 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000688 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000689 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000690
David BÉRARD0150c9c2010-05-11 10:17:53 +0200691#if defined(__DragonFly__)
692 /*
693 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
694 */
695 iph.ip_len = htons(iph.ip_len);
696#endif
697
paul0bfeca32004-09-24 08:07:54 +0000698#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000699 /* XXX-MT: not thread-safe at all..
700 * XXX: this presumes this is only programme sending OSPF packets
701 * otherwise, no guarantee ipid will be unique
702 */
703 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000704#endif /* WANT_OSPF_WRITE_FRAGMENT */
705
paul718e3742002-12-13 20:15:29 +0000706 iph.ip_off = 0;
707 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
708 iph.ip_ttl = OSPF_VL_IP_TTL;
709 else
710 iph.ip_ttl = OSPF_IP_TTL;
711 iph.ip_p = IPPROTO_OSPFIGP;
712 iph.ip_sum = 0;
713 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
714 iph.ip_dst.s_addr = op->dst.s_addr;
715
716 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000717 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000718 msg.msg_namelen = sizeof (sa_dst);
719 msg.msg_iov = iov;
720 msg.msg_iovlen = 2;
721 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000722 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
723 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000724 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000725
726 /* Sadly we can not rely on kernels to fragment packets because of either
727 * IP_HDRINCL and/or multicast destination being set.
728 */
paul0bfeca32004-09-24 08:07:54 +0000729#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000730 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000731 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
732 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000733#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000734
735 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000736 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000737 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000738 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000739
740 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000741 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000742 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000743 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000744 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000745
paul718e3742002-12-13 20:15:29 +0000746 /* Show debug sending packet. */
747 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
748 {
749 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
750 {
ajs2a42e282004-12-08 18:43:03 +0000751 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000752 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000753 stream_set_getp (op->s, 0);
754 ospf_packet_dump (op->s);
755 }
756
ajs2a42e282004-12-08 18:43:03 +0000757 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000758 ospf_packet_type_str[type], inet_ntoa (op->dst),
759 IF_NAME (oi));
760
761 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000762 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000763 }
764
765 /* Now delete packet from queue. */
766 ospf_packet_delete (oi);
767
768 if (ospf_fifo_head (oi->obuf) == NULL)
769 {
770 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000771 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000772 }
773
774 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000775 if (!list_isempty (ospf->oi_write_q))
776 ospf->t_write =
777 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000778
779 return 0;
780}
781
782/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000783static void
paul718e3742002-12-13 20:15:29 +0000784ospf_hello (struct ip *iph, struct ospf_header *ospfh,
785 struct stream * s, struct ospf_interface *oi, int size)
786{
787 struct ospf_hello *hello;
788 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000789 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000790 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000791
792 /* increment statistics. */
793 oi->hello_in++;
794
795 hello = (struct ospf_hello *) STREAM_PNT (s);
796
797 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000798 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000799 {
800 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
801 {
ajs2a42e282004-12-08 18:43:03 +0000802 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000803 "dropping.",
804 ospf_packet_type_str[ospfh->type],
805 inet_ntoa (iph->ip_src));
806 }
807 return;
808 }
paul718e3742002-12-13 20:15:29 +0000809
paul718e3742002-12-13 20:15:29 +0000810 /* get neighbor prefix. */
811 p.family = AF_INET;
812 p.prefixlen = ip_masklen (hello->network_mask);
813 p.u.prefix4 = iph->ip_src;
814
815 /* Compare network mask. */
816 /* Checking is ignored for Point-to-Point and Virtual link. */
817 if (oi->type != OSPF_IFTYPE_POINTOPOINT
818 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
819 if (oi->address->prefixlen != p.prefixlen)
820 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000821 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
822 inet_ntoa(ospfh->router_id), IF_NAME(oi),
823 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000824 return;
825 }
826
paul718e3742002-12-13 20:15:29 +0000827 /* Compare Router Dead Interval. */
828 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
829 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000830 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
831 "(expected %u, but received %u).",
832 inet_ntoa(ospfh->router_id),
833 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000834 return;
835 }
836
paulf9ad9372005-10-21 00:45:17 +0000837 /* Compare Hello Interval - ignored if fast-hellos are set. */
838 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
839 {
840 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
841 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000842 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
843 "(expected %u, but received %u).",
844 inet_ntoa(ospfh->router_id),
845 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000846 return;
847 }
848 }
849
paul718e3742002-12-13 20:15:29 +0000850 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000851 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000852 inet_ntoa (ospfh->router_id),
853 ospf_options_dump (hello->options));
854
855 /* Compare options. */
856#define REJECT_IF_TBIT_ON 1 /* XXX */
857#ifdef REJECT_IF_TBIT_ON
858 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
859 {
860 /*
861 * This router does not support non-zero TOS.
862 * Drop this Hello packet not to establish neighbor relationship.
863 */
864 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
865 inet_ntoa (ospfh->router_id));
866 return;
867 }
868#endif /* REJECT_IF_TBIT_ON */
869
870#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000871 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000872 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
873 {
874 /*
875 * This router does know the correct usage of O-bit
876 * the bit should be set in DD packet only.
877 */
878 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
879 inet_ntoa (ospfh->router_id));
880#ifdef STRICT_OBIT_USAGE_CHECK
881 return; /* Reject this packet. */
882#else /* STRICT_OBIT_USAGE_CHECK */
883 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
884#endif /* STRICT_OBIT_USAGE_CHECK */
885 }
886#endif /* HAVE_OPAQUE_LSA */
887
888 /* new for NSSA is to ensure that NP is on and E is off */
889
paul718e3742002-12-13 20:15:29 +0000890 if (oi->area->external_routing == OSPF_AREA_NSSA)
891 {
892 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
893 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
894 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
895 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
896 {
897 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
898 return;
899 }
900 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000901 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000902 }
903 else
paul718e3742002-12-13 20:15:29 +0000904 /* The setting of the E-bit found in the Hello Packet's Options
905 field must match this area's ExternalRoutingCapability A
906 mismatch causes processing to stop and the packet to be
907 dropped. The setting of the rest of the bits in the Hello
908 Packet's Options field should be ignored. */
909 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
910 CHECK_FLAG (hello->options, OSPF_OPTION_E))
911 {
ajs3aa8d5f2004-12-11 18:00:06 +0000912 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
913 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000914 return;
915 }
paul718e3742002-12-13 20:15:29 +0000916
pauld3f0d622004-05-05 15:27:15 +0000917 /* get neighbour struct */
918 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
919
920 /* neighbour must be valid, ospf_nbr_get creates if none existed */
921 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000922
923 old_state = nbr->state;
924
925 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000926 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000927
928 /* RFC2328 Section 9.5.1
929 If the router is not eligible to become Designated Router,
930 (snip) It must also send an Hello Packet in reply to an
931 Hello Packet received from any eligible neighbor (other than
932 the current Designated Router and Backup Designated Router). */
933 if (oi->type == OSPF_IFTYPE_NBMA)
934 if (PRIORITY(oi) == 0 && hello->priority > 0
935 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
936 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
937 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
938 OSPF_HELLO_REPLY_DELAY);
939
940 /* on NBMA network type, it happens to receive bidirectional Hello packet
941 without advance 1-Way Received event.
942 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
943 if (oi->type == OSPF_IFTYPE_NBMA &&
944 (old_state == NSM_Down || old_state == NSM_Attempt))
945 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000946 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000947 nbr->priority = hello->priority;
948 nbr->d_router = hello->d_router;
949 nbr->bd_router = hello->bd_router;
950 return;
951 }
952
paul68980082003-03-25 05:07:42 +0000953 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000954 size - OSPF_HELLO_MIN_SIZE))
955 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000956 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000957 nbr->options |= hello->options;
958 }
959 else
960 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000961 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000962 /* Set neighbor information. */
963 nbr->priority = hello->priority;
964 nbr->d_router = hello->d_router;
965 nbr->bd_router = hello->bd_router;
966 return;
967 }
968
969 /* If neighbor itself declares DR and no BDR exists,
970 cause event BackupSeen */
971 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
972 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
973 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
974
975 /* neighbor itself declares BDR. */
976 if (oi->state == ISM_Waiting &&
977 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
978 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
979
980 /* had not previously. */
981 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
982 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
983 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
984 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
985 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
986
987 /* had not previously. */
988 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
989 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
990 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
991 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
992 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
993
994 /* Neighbor priority check. */
995 if (nbr->priority >= 0 && nbr->priority != hello->priority)
996 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
997
998 /* Set neighbor information. */
999 nbr->priority = hello->priority;
1000 nbr->d_router = hello->d_router;
1001 nbr->bd_router = hello->bd_router;
1002}
1003
1004/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +00001005static void
paul718e3742002-12-13 20:15:29 +00001006ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1007 struct ospf_db_desc *dd)
1008{
1009 nbr->last_recv.flags = dd->flags;
1010 nbr->last_recv.options = dd->options;
1011 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1012}
1013
1014/* Process rest of DD packet. */
1015static void
1016ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1017 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1018 u_int16_t size)
1019{
1020 struct ospf_lsa *new, *find;
1021 struct lsa_header *lsah;
1022
paul9985f832005-02-09 15:51:56 +00001023 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001024 for (size -= OSPF_DB_DESC_MIN_SIZE;
1025 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1026 {
1027 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001028 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001029
1030 /* Unknown LS type. */
1031 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1032 {
ajsbec595a2004-11-30 22:38:43 +00001033 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001034 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1035 return;
1036 }
1037
1038#ifdef HAVE_OPAQUE_LSA
1039 if (IS_OPAQUE_LSA (lsah->type)
1040 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1041 {
1042 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1043 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1044 return;
1045 }
1046#endif /* HAVE_OPAQUE_LSA */
1047
1048 switch (lsah->type)
1049 {
1050 case OSPF_AS_EXTERNAL_LSA:
1051#ifdef HAVE_OPAQUE_LSA
1052 case OSPF_OPAQUE_AS_LSA:
1053#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001054 /* Check for stub area. Reject if AS-External from stub but
1055 allow if from NSSA. */
1056 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001057 {
1058 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1059 lsah->type, inet_ntoa (lsah->id),
1060 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1061 "STUB" : "NSSA");
1062 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1063 return;
1064 }
1065 break;
1066 default:
1067 break;
1068 }
1069
1070 /* Create LS-request object. */
1071 new = ospf_ls_request_new (lsah);
1072
1073 /* Lookup received LSA, then add LS request list. */
1074 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001075
1076 /* ospf_lsa_more_recent is fine with NULL pointers */
1077 switch (ospf_lsa_more_recent (find, new))
1078 {
1079 case -1:
1080 /* Neighbour has a more recent LSA, we must request it */
1081 ospf_ls_request_add (nbr, new);
1082 case 0:
1083 /* If we have a copy of this LSA, it's either less recent
1084 * and we're requesting it from neighbour (the case above), or
1085 * it's as recent and we both have same copy (this case).
1086 *
1087 * In neither of these two cases is there any point in
1088 * describing our copy of the LSA to the neighbour in a
1089 * DB-Summary packet, if we're still intending to do so.
1090 *
1091 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1092 * backward compatible optimisation to OSPF DB Exchange /
1093 * DB Description process implemented here.
1094 */
1095 if (find)
1096 ospf_lsdb_delete (&nbr->db_sum, find);
1097 ospf_lsa_discard (new);
1098 break;
1099 default:
1100 /* We have the more recent copy, nothing specific to do:
1101 * - no need to request neighbours stale copy
1102 * - must leave DB summary list copy alone
1103 */
1104 if (IS_DEBUG_OSPF_EVENT)
1105 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1106 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1107 ospf_lsa_discard (new);
1108 }
paul718e3742002-12-13 20:15:29 +00001109 }
1110
1111 /* Master */
1112 if (IS_SET_DD_MS (nbr->dd_flags))
1113 {
1114 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001115
1116 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001117 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1118 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1119 else
paul718e3742002-12-13 20:15:29 +00001120 ospf_db_desc_send (nbr);
1121 }
1122 /* Slave */
1123 else
1124 {
1125 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1126
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001127 /* Send DD packet in reply.
1128 *
1129 * Must be done to acknowledge the Master's DD, regardless of
1130 * whether we have more LSAs ourselves to describe.
1131 *
1132 * This function will clear the 'More' bit, if after this DD
1133 * we have no more LSAs to describe to the master..
1134 */
paul718e3742002-12-13 20:15:29 +00001135 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001136
1137 /* Slave can raise ExchangeDone now, if master is also done */
1138 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1139 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001140 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001141
paul718e3742002-12-13 20:15:29 +00001142 /* Save received neighbor values from DD. */
1143 ospf_db_desc_save_current (nbr, dd);
1144}
1145
paul4dadc292005-05-06 21:37:42 +00001146static int
paul718e3742002-12-13 20:15:29 +00001147ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1148{
1149 /* Is DD duplicated? */
1150 if (dd->options == nbr->last_recv.options &&
1151 dd->flags == nbr->last_recv.flags &&
1152 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1153 return 1;
1154
1155 return 0;
1156}
1157
1158/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001159static void
paul718e3742002-12-13 20:15:29 +00001160ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1161 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1162{
1163 struct ospf_db_desc *dd;
1164 struct ospf_neighbor *nbr;
1165
1166 /* Increment statistics. */
1167 oi->db_desc_in++;
1168
1169 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001170
pauld3f0d622004-05-05 15:27:15 +00001171 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001172 if (nbr == NULL)
1173 {
1174 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1175 inet_ntoa (ospfh->router_id));
1176 return;
1177 }
1178
1179 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001180 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1181 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001182 {
ajs3aa8d5f2004-12-11 18:00:06 +00001183 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1184 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1185 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001186 return;
1187 }
1188
pauld363df22003-06-19 00:26:34 +00001189 /*
1190 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1191 * required. In fact at least JunOS sends DD packets with P bit clear.
1192 * Until proper solution is developped, this hack should help.
1193 *
1194 * Update: According to the RFCs, N bit is specified /only/ for Hello
1195 * options, unfortunately its use in DD options is not specified. Hence some
1196 * implementations follow E-bit semantics and set it in DD options, and some
1197 * treat it as unspecified and hence follow the directive "default for
1198 * options is clear", ie unset.
1199 *
1200 * Reset the flag, as ospfd follows E-bit semantics.
1201 */
1202 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1203 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1204 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1205 {
1206 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001207 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001208 inet_ntoa (nbr->router_id) );
1209 SET_FLAG (dd->options, OSPF_OPTION_NP);
1210 }
pauld363df22003-06-19 00:26:34 +00001211
paul718e3742002-12-13 20:15:29 +00001212#ifdef REJECT_IF_TBIT_ON
1213 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1214 {
1215 /*
1216 * In Hello protocol, optional capability must have checked
1217 * to prevent this T-bit enabled router be my neighbor.
1218 */
1219 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1220 return;
1221 }
1222#endif /* REJECT_IF_TBIT_ON */
1223
1224#ifdef HAVE_OPAQUE_LSA
1225 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001226 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001227 {
1228 /*
1229 * This node is not configured to handle O-bit, for now.
1230 * Clear it to ignore unsupported capability proposed by neighbor.
1231 */
1232 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1233 }
1234#endif /* HAVE_OPAQUE_LSA */
1235
Paul Jakma57c5c652010-01-07 06:12:53 +00001236 /* Add event to thread. */
1237 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1238
paul718e3742002-12-13 20:15:29 +00001239 /* Process DD packet by neighbor status. */
1240 switch (nbr->state)
1241 {
1242 case NSM_Down:
1243 case NSM_Attempt:
1244 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001245 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001246 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001247 LOOKUP (ospf_nsm_state_msg, nbr->state));
1248 break;
1249 case NSM_Init:
1250 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1251 /* If the new state is ExStart, the processing of the current
1252 packet should then continue in this new state by falling
1253 through to case ExStart below. */
1254 if (nbr->state != NSM_ExStart)
1255 break;
1256 case NSM_ExStart:
1257 /* Initial DBD */
1258 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1259 (size == OSPF_DB_DESC_MIN_SIZE))
1260 {
paul68980082003-03-25 05:07:42 +00001261 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001262 {
1263 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001264 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001265 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001266 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001267
1268 /* Reset I/MS */
1269 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001270 }
1271 else
1272 {
1273 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001274 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001275 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001276 break;
1277 }
1278 }
1279 /* Ack from the Slave */
1280 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1281 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001282 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001283 {
ajs17eaa722004-12-29 21:04:48 +00001284 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001285 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001286 /* Reset I, leaving MS */
1287 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001288 }
1289 else
1290 {
ajs3aa8d5f2004-12-11 18:00:06 +00001291 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1292 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001293 break;
1294 }
1295
1296 /* This is where the real Options are saved */
1297 nbr->options = dd->options;
1298
1299#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001300 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001301 {
1302 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001303 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001304 inet_ntoa (nbr->router_id),
1305 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1306
1307 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1308 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1309 {
paul6d452762005-11-03 11:15:44 +00001310 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1311 "Opaque-LSAs cannot be reliably advertised "
1312 "in this network.",
1313 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001314 /* This situation is undesirable, but not a real error. */
1315 }
1316 }
1317#endif /* HAVE_OPAQUE_LSA */
1318
1319 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1320
1321 /* continue processing rest of packet. */
1322 ospf_db_desc_proc (s, oi, nbr, dd, size);
1323 break;
1324 case NSM_Exchange:
1325 if (ospf_db_desc_is_dup (dd, nbr))
1326 {
1327 if (IS_SET_DD_MS (nbr->dd_flags))
1328 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001329 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001330 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001331 else
1332 /* Slave: cause to retransmit the last Database Description. */
1333 {
paul6d452762005-11-03 11:15:44 +00001334 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001335 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001336 ospf_db_desc_resend (nbr);
1337 }
1338 break;
1339 }
1340
1341 /* Otherwise DD packet should be checked. */
1342 /* Check Master/Slave bit mismatch */
1343 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1344 {
ajs3aa8d5f2004-12-11 18:00:06 +00001345 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1346 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001347 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1348 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001349 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001350 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001351 break;
1352 }
1353
1354 /* Check initialize bit is set. */
1355 if (IS_SET_DD_I (dd->flags))
1356 {
paul6d452762005-11-03 11:15:44 +00001357 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001358 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001359 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1360 break;
1361 }
1362
1363 /* Check DD Options. */
1364 if (dd->options != nbr->options)
1365 {
1366#ifdef ORIGINAL_CODING
1367 /* Save the new options for debugging */
1368 nbr->options = dd->options;
1369#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001370 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1371 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001372 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1373 break;
1374 }
1375
1376 /* Check DD sequence number. */
1377 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1378 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1379 (!IS_SET_DD_MS (nbr->dd_flags) &&
1380 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1381 {
ajs3aa8d5f2004-12-11 18:00:06 +00001382 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1383 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001384 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1385 break;
1386 }
1387
1388 /* Continue processing rest of packet. */
1389 ospf_db_desc_proc (s, oi, nbr, dd, size);
1390 break;
1391 case NSM_Loading:
1392 case NSM_Full:
1393 if (ospf_db_desc_is_dup (dd, nbr))
1394 {
1395 if (IS_SET_DD_MS (nbr->dd_flags))
1396 {
1397 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001398 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1399 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001400 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001401 break;
1402 }
1403 else
1404 {
1405 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001406 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001407 t = tv_sub (now, nbr->last_send_ts);
1408 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1409 {
1410 /* In states Loading and Full the slave must resend
1411 its last Database Description packet in response to
1412 duplicate Database Description packets received
1413 from the master. For this reason the slave must
1414 wait RouterDeadInterval seconds before freeing the
1415 last Database Description packet. Reception of a
1416 Database Description packet from the master after
1417 this interval will generate a SeqNumberMismatch
1418 neighbor event. RFC2328 Section 10.8 */
1419 ospf_db_desc_resend (nbr);
1420 break;
1421 }
1422 }
1423 }
1424
1425 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1426 break;
1427 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001428 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1429 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001430 break;
1431 }
1432}
1433
1434#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1435
1436/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001437static void
paul718e3742002-12-13 20:15:29 +00001438ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1439 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1440{
1441 struct ospf_neighbor *nbr;
1442 u_int32_t ls_type;
1443 struct in_addr ls_id;
1444 struct in_addr adv_router;
1445 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001446 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001447 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001448
1449 /* Increment statistics. */
1450 oi->ls_req_in++;
1451
pauld3f0d622004-05-05 15:27:15 +00001452 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001453 if (nbr == NULL)
1454 {
1455 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1456 inet_ntoa (ospfh->router_id));
1457 return;
1458 }
1459
Paul Jakma57c5c652010-01-07 06:12:53 +00001460 /* Add event to thread. */
1461 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1462
paul718e3742002-12-13 20:15:29 +00001463 /* Neighbor State should be Exchange or later. */
1464 if (nbr->state != NSM_Exchange &&
1465 nbr->state != NSM_Loading &&
1466 nbr->state != NSM_Full)
1467 {
ajsbec595a2004-11-30 22:38:43 +00001468 zlog_warn ("Link State Request received from %s: "
1469 "Neighbor state is %s, packet discarded.",
1470 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001471 LOOKUP (ospf_nsm_state_msg, nbr->state));
1472 return;
1473 }
1474
1475 /* Send Link State Update for ALL requested LSAs. */
1476 ls_upd = list_new ();
1477 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1478
1479 while (size >= OSPF_LSA_KEY_SIZE)
1480 {
1481 /* Get one slice of Link State Request. */
1482 ls_type = stream_getl (s);
1483 ls_id.s_addr = stream_get_ipv4 (s);
1484 adv_router.s_addr = stream_get_ipv4 (s);
1485
1486 /* Verify LSA type. */
1487 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1488 {
1489 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1490 list_delete (ls_upd);
1491 return;
1492 }
1493
1494 /* Search proper LSA in LSDB. */
1495 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1496 if (find == NULL)
1497 {
1498 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1499 list_delete (ls_upd);
1500 return;
1501 }
1502
gdt86f1fd92005-01-10 14:20:43 +00001503 /* Packet overflows MTU size, send immediately. */
1504 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001505 {
1506 if (oi->type == OSPF_IFTYPE_NBMA)
1507 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1508 else
1509 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1510
1511 /* Only remove list contents. Keep ls_upd. */
1512 list_delete_all_node (ls_upd);
1513
1514 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1515 }
1516
1517 /* Append LSA to update list. */
1518 listnode_add (ls_upd, find);
1519 length += ntohs (find->data->length);
1520
1521 size -= OSPF_LSA_KEY_SIZE;
1522 }
1523
1524 /* Send rest of Link State Update. */
1525 if (listcount (ls_upd) > 0)
1526 {
1527 if (oi->type == OSPF_IFTYPE_NBMA)
1528 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1529 else
1530 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1531
1532 list_delete (ls_upd);
1533 }
1534 else
1535 list_free (ls_upd);
1536}
1537
1538/* Get the list of LSAs from Link State Update packet.
1539 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001540static struct list *
paul718e3742002-12-13 20:15:29 +00001541ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1542 struct ospf_interface *oi, size_t size)
1543{
1544 u_int16_t count, sum;
1545 u_int32_t length;
1546 struct lsa_header *lsah;
1547 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001548 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001549
1550 lsas = list_new ();
1551
1552 count = stream_getl (s);
1553 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1554
1555 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001556 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001557 {
1558 lsah = (struct lsa_header *) STREAM_PNT (s);
1559 length = ntohs (lsah->length);
1560
1561 if (length > size)
1562 {
1563 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1564 break;
1565 }
1566
1567 /* Validate the LSA's LS checksum. */
1568 sum = lsah->checksum;
1569 if (sum != ospf_lsa_checksum (lsah))
1570 {
1571 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1572 sum, lsah->checksum);
1573 continue;
1574 }
1575
1576 /* Examine the LSA's LS type. */
1577 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1578 {
1579 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1580 continue;
1581 }
1582
1583 /*
1584 * What if the received LSA's age is greater than MaxAge?
1585 * Treat it as a MaxAge case -- endo.
1586 */
1587 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1588 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1589
1590#ifdef HAVE_OPAQUE_LSA
1591 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1592 {
1593#ifdef STRICT_OBIT_USAGE_CHECK
1594 if ((IS_OPAQUE_LSA(lsah->type) &&
1595 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1596 || (! IS_OPAQUE_LSA(lsah->type) &&
1597 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1598 {
1599 /*
1600 * This neighbor must know the exact usage of O-bit;
1601 * the bit will be set in Type-9,10,11 LSAs only.
1602 */
1603 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1604 continue;
1605 }
1606#endif /* STRICT_OBIT_USAGE_CHECK */
1607
1608 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1609 if (lsah->type == OSPF_OPAQUE_AS_LSA
1610 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1611 {
1612 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001613 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 +00001614 continue;
1615 }
1616 }
1617 else if (IS_OPAQUE_LSA(lsah->type))
1618 {
1619 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1620 continue;
1621 }
1622#endif /* HAVE_OPAQUE_LSA */
1623
1624 /* Create OSPF LSA instance. */
1625 lsa = ospf_lsa_new ();
1626
1627 /* We may wish to put some error checking if type NSSA comes in
1628 and area not in NSSA mode */
1629 switch (lsah->type)
1630 {
1631 case OSPF_AS_EXTERNAL_LSA:
1632#ifdef HAVE_OPAQUE_LSA
1633 case OSPF_OPAQUE_AS_LSA:
1634 lsa->area = NULL;
1635 break;
1636 case OSPF_OPAQUE_LINK_LSA:
1637 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1638 /* Fallthrough */
1639#endif /* HAVE_OPAQUE_LSA */
1640 default:
1641 lsa->area = oi->area;
1642 break;
1643 }
1644
1645 lsa->data = ospf_lsa_data_new (length);
1646 memcpy (lsa->data, lsah, length);
1647
1648 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001649 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001650 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1651 listnode_add (lsas, lsa);
1652 }
1653
1654 return lsas;
1655}
1656
1657/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001658static void
hasso52dc7ee2004-09-23 19:18:23 +00001659ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001660{
paul1eb8ef22005-04-07 07:30:20 +00001661 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001662 struct ospf_lsa *lsa;
1663
paul1eb8ef22005-04-07 07:30:20 +00001664 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1665 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001666
1667 list_delete (lsas);
1668}
1669
1670/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001671static void
paul718e3742002-12-13 20:15:29 +00001672ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1673 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1674{
1675 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001676 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001677 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001678 struct ospf_lsa *lsa = NULL;
1679 /* unsigned long ls_req_found = 0; */
1680
1681 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1682
1683 /* Increment statistics. */
1684 oi->ls_upd_in++;
1685
1686 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001687 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001688 if (nbr == NULL)
1689 {
1690 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1691 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1692 return;
1693 }
1694
Paul Jakma57c5c652010-01-07 06:12:53 +00001695 /* Add event to thread. */
1696 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1697
paul718e3742002-12-13 20:15:29 +00001698 /* Check neighbor state. */
1699 if (nbr->state < NSM_Exchange)
1700 {
ajs3aa8d5f2004-12-11 18:00:06 +00001701 zlog_warn ("Link State Update: "
1702 "Neighbor[%s] state %s is less than Exchange",
1703 inet_ntoa (ospfh->router_id),
1704 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001705 return;
1706 }
1707
1708 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1709 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1710 * of section 13.
1711 */
1712 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1713
1714#ifdef HAVE_OPAQUE_LSA
1715 /*
paul718e3742002-12-13 20:15:29 +00001716 * If self-originated Opaque-LSAs that have flooded before restart
1717 * are contained in the received LSUpd message, corresponding LSReq
1718 * messages to be sent may have to be modified.
1719 * To eliminate possible race conditions such that flushing and normal
1720 * updating for the same LSA would take place alternately, this trick
1721 * must be done before entering to the loop below.
1722 */
paul69310a62005-05-11 18:09:59 +00001723 /* XXX: Why is this Opaque specific? Either our core code is deficient
1724 * and this should be fixed generally, or Opaque is inventing strawman
1725 * problems */
paul718e3742002-12-13 20:15:29 +00001726 ospf_opaque_adjust_lsreq (nbr, lsas);
1727#endif /* HAVE_OPAQUE_LSA */
1728
1729#define DISCARD_LSA(L,N) {\
1730 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001731 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 +00001732 ospf_lsa_discard (L); \
1733 continue; }
1734
1735 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001736 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001737 {
1738 struct ospf_lsa *ls_ret, *current;
1739 int ret = 1;
1740
paul718e3742002-12-13 20:15:29 +00001741 if (IS_DEBUG_OSPF_NSSA)
1742 {
1743 char buf1[INET_ADDRSTRLEN];
1744 char buf2[INET_ADDRSTRLEN];
1745 char buf3[INET_ADDRSTRLEN];
1746
ajs2a42e282004-12-08 18:43:03 +00001747 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001748 lsa->data->type,
1749 inet_ntop (AF_INET, &ospfh->router_id,
1750 buf1, INET_ADDRSTRLEN),
1751 inet_ntop (AF_INET, &lsa->data->id,
1752 buf2, INET_ADDRSTRLEN),
1753 inet_ntop (AF_INET, &lsa->data->adv_router,
1754 buf3, INET_ADDRSTRLEN));
1755 }
paul718e3742002-12-13 20:15:29 +00001756
1757 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1758
1759 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1760
1761 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1762
1763 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1764
1765 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1766
1767 /* Do take in Type-7's if we are an NSSA */
1768
1769 /* If we are also an ABR, later translate them to a Type-5 packet */
1770
1771 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1772 translate them to a separate Type-5 packet. */
1773
1774 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1775 /* Reject from STUB or NSSA */
1776 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1777 {
paul718e3742002-12-13 20:15:29 +00001778 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001779 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001780 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001781 }
1782
paul718e3742002-12-13 20:15:29 +00001783 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1784 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1785 {
paul718e3742002-12-13 20:15:29 +00001786 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001787 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001788 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001789 }
paul718e3742002-12-13 20:15:29 +00001790
1791 /* Find the LSA in the current database. */
1792
1793 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1794
1795 /* If the LSA's LS age is equal to MaxAge, and there is currently
1796 no instance of the LSA in the router's link state database,
1797 and none of router's neighbors are in states Exchange or Loading,
1798 then take the following actions. */
1799
1800 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001801 (ospf_nbr_count (oi, NSM_Exchange) +
1802 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001803 {
1804 /* Response Link State Acknowledgment. */
1805 ospf_ls_ack_send (nbr, lsa);
1806
1807 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001808 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1809 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001810 DISCARD_LSA (lsa, 3);
1811 }
1812
1813#ifdef HAVE_OPAQUE_LSA
1814 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001815 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001816 {
1817 /*
1818 * Even if initial flushing seems to be completed, there might
1819 * be a case that self-originated LSA with MaxAge still remain
1820 * in the routing domain.
1821 * Just send an LSAck message to cease retransmission.
1822 */
1823 if (IS_LSA_MAXAGE (lsa))
1824 {
1825 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1826 ospf_ls_ack_send (nbr, lsa);
1827 ospf_lsa_discard (lsa);
1828
1829 if (current != NULL && ! IS_LSA_MAXAGE (current))
1830 ospf_opaque_lsa_refresh_schedule (current);
1831 continue;
1832 }
1833
1834 /*
1835 * If an instance of self-originated Opaque-LSA is not found
1836 * in the LSDB, there are some possible cases here.
1837 *
1838 * 1) This node lost opaque-capability after restart.
1839 * 2) Else, a part of opaque-type is no more supported.
1840 * 3) Else, a part of opaque-id is no more supported.
1841 *
1842 * Anyway, it is still this node's responsibility to flush it.
1843 * Otherwise, the LSA instance remains in the routing domain
1844 * until its age reaches to MaxAge.
1845 */
paul69310a62005-05-11 18:09:59 +00001846 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001847 if (current == NULL)
1848 {
1849 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001850 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1851 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001852
1853 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001854
1855 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1856 ospf_ls_ack_send (nbr, lsa);
1857
paul718e3742002-12-13 20:15:29 +00001858 continue;
1859 }
1860 }
1861#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001862
hassocb05eb22004-02-11 21:10:19 +00001863 /* It might be happen that received LSA is self-originated network LSA, but
1864 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1865 * Link State ID is one of the router's own IP interface addresses but whose
1866 * Advertising Router is not equal to the router's own Router ID
1867 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1868 */
1869
1870 if(lsa->data->type == OSPF_NETWORK_LSA)
1871 {
paul1eb8ef22005-04-07 07:30:20 +00001872 struct listnode *oinode, *oinnode;
1873 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001874 int Flag = 0;
1875
paul1eb8ef22005-04-07 07:30:20 +00001876 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001877 {
hassocb05eb22004-02-11 21:10:19 +00001878 if(out_if == NULL)
1879 break;
1880
1881 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1882 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1883 {
1884 if(out_if->network_lsa_self)
1885 {
1886 ospf_lsa_flush_area(lsa,out_if->area);
1887 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001888 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001889 lsa, (int) lsa->data->type);
1890 ospf_lsa_discard (lsa);
1891 Flag = 1;
1892 }
1893 break;
1894 }
1895 }
1896 if(Flag)
1897 continue;
1898 }
paul718e3742002-12-13 20:15:29 +00001899
1900 /* (5) Find the instance of this LSA that is currently contained
1901 in the router's link state database. If there is no
1902 database copy, or the received LSA is more recent than
1903 the database copy the following steps must be performed. */
1904
1905 if (current == NULL ||
1906 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1907 {
1908 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001909 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001910 DISCARD_LSA (lsa, 4);
1911 continue;
1912 }
1913
1914 /* (6) Else, If there is an instance of the LSA on the sending
1915 neighbor's Link state request list, an error has occurred in
1916 the Database Exchange process. In this case, restart the
1917 Database Exchange process by generating the neighbor event
1918 BadLSReq for the sending neighbor and stop processing the
1919 Link State Update packet. */
1920
1921 if (ospf_ls_request_lookup (nbr, lsa))
1922 {
1923 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001924 zlog_warn("LSA[%s] instance exists on Link state request list",
1925 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001926
1927 /* Clean list of LSAs. */
1928 ospf_upd_list_clean (lsas);
1929 /* this lsa is not on lsas list already. */
1930 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001931 return;
1932 }
1933
1934 /* If the received LSA is the same instance as the database copy
1935 (i.e., neither one is more recent) the following two steps
1936 should be performed: */
1937
1938 if (ret == 0)
1939 {
1940 /* If the LSA is listed in the Link state retransmission list
1941 for the receiving adjacency, the router itself is expecting
1942 an acknowledgment for this LSA. The router should treat the
1943 received LSA as an acknowledgment by removing the LSA from
1944 the Link state retransmission list. This is termed an
1945 "implied acknowledgment". */
1946
1947 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1948
1949 if (ls_ret != NULL)
1950 {
1951 ospf_ls_retransmit_delete (nbr, ls_ret);
1952
1953 /* Delayed acknowledgment sent if advertisement received
1954 from Designated Router, otherwise do nothing. */
1955 if (oi->state == ISM_Backup)
1956 if (NBR_IS_DR (nbr))
1957 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1958
1959 DISCARD_LSA (lsa, 5);
1960 }
1961 else
1962 /* Acknowledge the receipt of the LSA by sending a
1963 Link State Acknowledgment packet back out the receiving
1964 interface. */
1965 {
1966 ospf_ls_ack_send (nbr, lsa);
1967 DISCARD_LSA (lsa, 6);
1968 }
1969 }
1970
1971 /* The database copy is more recent. If the database copy
1972 has LS age equal to MaxAge and LS sequence number equal to
1973 MaxSequenceNumber, simply discard the received LSA without
1974 acknowledging it. (In this case, the LSA's LS sequence number is
1975 wrapping, and the MaxSequenceNumber LSA must be completely
1976 flushed before any new LSA instance can be introduced). */
1977
1978 else if (ret > 0) /* Database copy is more recent */
1979 {
1980 if (IS_LSA_MAXAGE (current) &&
1981 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1982 {
1983 DISCARD_LSA (lsa, 7);
1984 }
1985 /* Otherwise, as long as the database copy has not been sent in a
1986 Link State Update within the last MinLSArrival seconds, send the
1987 database copy back to the sending neighbor, encapsulated within
1988 a Link State Update Packet. The Link State Update Packet should
1989 be sent directly to the neighbor. In so doing, do not put the
1990 database copy of the LSA on the neighbor's link state
1991 retransmission list, and do not acknowledge the received (less
1992 recent) LSA instance. */
1993 else
1994 {
1995 struct timeval now;
1996
Paul Jakma2518efd2006-08-27 06:49:29 +00001997 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001998
1999 if (tv_cmp (tv_sub (now, current->tv_orig),
Paul Jakma2c9f8e32010-01-11 16:22:12 +00002000 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
paul718e3742002-12-13 20:15:29 +00002001 /* Trap NSSA type later.*/
2002 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2003 DISCARD_LSA (lsa, 8);
2004 }
2005 }
2006 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002007#undef DISCARD_LSA
2008
paul718e3742002-12-13 20:15:29 +00002009 assert (listcount (lsas) == 0);
2010 list_delete (lsas);
2011}
2012
2013/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002014static void
paul718e3742002-12-13 20:15:29 +00002015ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2016 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2017{
2018 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002019
paul718e3742002-12-13 20:15:29 +00002020 /* increment statistics. */
2021 oi->ls_ack_in++;
2022
pauld3f0d622004-05-05 15:27:15 +00002023 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002024 if (nbr == NULL)
2025 {
2026 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2027 inet_ntoa (ospfh->router_id));
2028 return;
2029 }
2030
Paul Jakma57c5c652010-01-07 06:12:53 +00002031 /* Add event to thread. */
2032 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2033
paul718e3742002-12-13 20:15:29 +00002034 if (nbr->state < NSM_Exchange)
2035 {
ajs3aa8d5f2004-12-11 18:00:06 +00002036 zlog_warn ("Link State Acknowledgment: "
2037 "Neighbor[%s] state %s is less than Exchange",
2038 inet_ntoa (ospfh->router_id),
2039 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002040 return;
2041 }
paul69310a62005-05-11 18:09:59 +00002042
paul718e3742002-12-13 20:15:29 +00002043 while (size >= OSPF_LSA_HEADER_SIZE)
2044 {
2045 struct ospf_lsa *lsa, *lsr;
2046
2047 lsa = ospf_lsa_new ();
2048 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2049
2050 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2051 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002052 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002053
2054 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2055 {
2056 lsa->data = NULL;
2057 ospf_lsa_discard (lsa);
2058 continue;
2059 }
2060
2061 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2062
2063 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2064 {
2065#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002066 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002067 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002068#endif /* HAVE_OPAQUE_LSA */
2069
2070 ospf_ls_retransmit_delete (nbr, lsr);
2071 }
2072
2073 lsa->data = NULL;
2074 ospf_lsa_discard (lsa);
2075 }
2076
paul718e3742002-12-13 20:15:29 +00002077 return;
paul718e3742002-12-13 20:15:29 +00002078}
2079
ajs038163f2005-02-17 19:55:59 +00002080static struct stream *
ajs5c333492005-02-23 15:43:01 +00002081ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002082{
2083 int ret;
ajs5c333492005-02-23 15:43:01 +00002084 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002085 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002086 unsigned int ifindex = 0;
2087 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002088 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002089 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002090 struct msghdr msgh;
2091
paul68defd62004-09-27 07:27:13 +00002092 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002093 msgh.msg_iov = &iov;
2094 msgh.msg_iovlen = 1;
2095 msgh.msg_control = (caddr_t) buff;
2096 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002097
ajs5c333492005-02-23 15:43:01 +00002098 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2099 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002100 {
ajs5c333492005-02-23 15:43:01 +00002101 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2102 return NULL;
2103 }
paul69310a62005-05-11 18:09:59 +00002104 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002105 {
2106 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2107 "(ip header size is %u)",
2108 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002109 return NULL;
2110 }
paul18b12c32004-10-05 14:38:29 +00002111
ajs5c333492005-02-23 15:43:01 +00002112 /* Note that there should not be alignment problems with this assignment
2113 because this is at the beginning of the stream data buffer. */
2114 iph = (struct ip *) STREAM_DATA(ibuf);
2115 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002116
ajs5c333492005-02-23 15:43:01 +00002117 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002118
paul239aecc2003-12-08 10:34:54 +00002119#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002120 /*
2121 * Kernel network code touches incoming IP header parameters,
2122 * before protocol specific processing.
2123 *
2124 * 1) Convert byteorder to host representation.
2125 * --> ip_len, ip_id, ip_off
2126 *
2127 * 2) Adjust ip_len to strip IP header size!
2128 * --> If user process receives entire IP packet via RAW
2129 * socket, it must consider adding IP header size to
2130 * the "ip_len" field of "ip" structure.
2131 *
2132 * For more details, see <netinet/ip_input.c>.
2133 */
ajs5c333492005-02-23 15:43:01 +00002134 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002135#endif
2136
David BÉRARD0150c9c2010-05-11 10:17:53 +02002137#if defined(__DragonFly__)
2138 /*
2139 * in DragonFly's raw socket, ip_len/ip_off are read
2140 * in network byte order.
2141 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2142 */
2143 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2144#endif
2145
paul863082d2004-08-19 04:43:43 +00002146 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002147
2148 *ifp = if_lookup_by_index (ifindex);
2149
2150 if (ret != ip_len)
2151 {
ajs5c333492005-02-23 15:43:01 +00002152 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2153 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002154 return NULL;
2155 }
2156
2157 return ibuf;
2158}
2159
paul4dadc292005-05-06 21:37:42 +00002160static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002161ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002162 struct ip *iph, struct ospf_header *ospfh)
2163{
2164 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002165 struct ospf_vl_data *vl_data;
2166 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002167 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002168
2169 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2170 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002171 return NULL;
paul718e3742002-12-13 20:15:29 +00002172
pauld3f0d622004-05-05 15:27:15 +00002173 /* look for local OSPF interface matching the destination
2174 * to determine Area ID. We presume therefore the destination address
2175 * is unique, or at least (for "unnumbered" links), not used in other
2176 * areas
2177 */
2178 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2179 iph->ip_dst)) == NULL)
2180 return NULL;
paul718e3742002-12-13 20:15:29 +00002181
paul1eb8ef22005-04-07 07:30:20 +00002182 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002183 {
paul020709f2003-04-04 02:44:16 +00002184 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002185 if (!vl_area)
2186 continue;
2187
2188 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2189 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2190 {
2191 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002192 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002193 IF_NAME (vl_data->vl_oi));
2194 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2195 {
2196 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002197 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002198 return NULL;
2199 }
2200
2201 return vl_data->vl_oi;
2202 }
2203 }
2204
2205 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002206 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002207
pauld3f0d622004-05-05 15:27:15 +00002208 return NULL;
paul718e3742002-12-13 20:15:29 +00002209}
2210
paul4dadc292005-05-06 21:37:42 +00002211static inline int
paul718e3742002-12-13 20:15:29 +00002212ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2213{
2214 /* Check match the Area ID of the receiving interface. */
2215 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2216 return 1;
2217
2218 return 0;
2219}
2220
2221/* Unbound socket will accept any Raw IP packets if proto is matched.
2222 To prevent it, compare src IP address and i/f address with masking
2223 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002224static int
paul718e3742002-12-13 20:15:29 +00002225ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2226{
2227 struct in_addr mask, me, him;
2228
2229 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2230 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2231 return 1;
2232
2233 masklen2ip (oi->address->prefixlen, &mask);
2234
2235 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2236 him.s_addr = ip_src.s_addr & mask.s_addr;
2237
2238 if (IPV4_ADDR_SAME (&me, &him))
2239 return 1;
2240
2241 return 0;
2242}
2243
paul4dadc292005-05-06 21:37:42 +00002244static int
paul718e3742002-12-13 20:15:29 +00002245ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2246 struct ospf_header *ospfh)
2247{
2248 int ret = 0;
2249 struct crypt_key *ck;
2250
2251 switch (ntohs (ospfh->auth_type))
2252 {
2253 case OSPF_AUTH_NULL:
2254 ret = 1;
2255 break;
2256 case OSPF_AUTH_SIMPLE:
2257 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2258 ret = 1;
2259 else
2260 ret = 0;
2261 break;
2262 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002263 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002264 {
2265 ret = 0;
2266 break;
2267 }
2268
2269 /* This is very basic, the digest processing is elsewhere */
2270 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2271 ospfh->u.crypt.key_id == ck->key_id &&
2272 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2273 ret = 1;
2274 else
2275 ret = 0;
2276 break;
2277 default:
2278 ret = 0;
2279 break;
2280 }
2281
2282 return ret;
2283}
2284
paul4dadc292005-05-06 21:37:42 +00002285static int
paul718e3742002-12-13 20:15:29 +00002286ospf_check_sum (struct ospf_header *ospfh)
2287{
2288 u_int32_t ret;
2289 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002290
2291 /* clear auth_data for checksum. */
2292 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2293
2294 /* keep checksum and clear. */
2295 sum = ospfh->checksum;
2296 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2297
2298 /* calculate checksum. */
2299 ret = in_cksum (ospfh, ntohs (ospfh->length));
2300
2301 if (ret != sum)
2302 {
2303 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2304 ret, sum);
2305 return 0;
2306 }
2307
2308 return 1;
2309}
2310
2311/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002312static int
paul718e3742002-12-13 20:15:29 +00002313ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2314 struct ip *iph, struct ospf_header *ospfh)
2315{
2316 /* check version. */
2317 if (ospfh->version != OSPF_VERSION)
2318 {
2319 zlog_warn ("interface %s: ospf_read version number mismatch.",
2320 IF_NAME (oi));
2321 return -1;
2322 }
2323
Denis Ovsienko71775042011-09-26 13:18:02 +04002324 /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
2325 if (ospfh->type < 1 || ospfh->type > 5)
2326 {
2327 zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
2328 return -1;
2329 }
2330
paul718e3742002-12-13 20:15:29 +00002331 /* Check Area ID. */
2332 if (!ospf_check_area_id (oi, ospfh))
2333 {
2334 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2335 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2336 return -1;
2337 }
2338
2339 /* Check network mask, Silently discarded. */
2340 if (! ospf_check_network_mask (oi, iph->ip_src))
2341 {
2342 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2343 IF_NAME (oi), inet_ntoa (iph->ip_src));
2344 return -1;
2345 }
2346
2347 /* Check authentication. */
2348 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2349 {
paulc6371712006-01-17 17:49:53 +00002350 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2351 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002352 return -1;
2353 }
2354
2355 if (! ospf_check_auth (oi, ibuf, ospfh))
2356 {
2357 zlog_warn ("interface %s: ospf_read authentication failed.",
2358 IF_NAME (oi));
2359 return -1;
2360 }
2361
2362 /* if check sum is invalid, packet is discarded. */
2363 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2364 {
2365 if (! ospf_check_sum (ospfh))
2366 {
2367 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2368 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2369 return -1;
2370 }
2371 }
2372 else
2373 {
2374 if (ospfh->checksum != 0)
2375 return -1;
2376 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2377 {
2378 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2379 IF_NAME (oi));
2380 return -1;
2381 }
2382 }
2383
2384 return 0;
2385}
2386
2387/* Starting point of packet process function. */
2388int
2389ospf_read (struct thread *thread)
2390{
2391 int ret;
2392 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002393 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002394 struct ospf_interface *oi;
2395 struct ip *iph;
2396 struct ospf_header *ospfh;
2397 u_int16_t length;
2398 struct interface *ifp;
2399
2400 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002401 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002402
2403 /* prepare for next packet. */
2404 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002405
2406 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002407 stream_reset(ospf->ibuf);
2408 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002409 return -1;
2410
ajs5c333492005-02-23 15:43:01 +00002411 /* Note that there should not be alignment problems with this assignment
2412 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002413 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002414 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002415
paulac191232004-10-22 12:05:17 +00002416 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002417 /* Handle cases where the platform does not support retrieving the ifindex,
2418 and also platforms (such as Solaris 8) that claim to support ifindex
2419 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002420 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002421
pauld3f0d622004-05-05 15:27:15 +00002422 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002423 return 0;
paul718e3742002-12-13 20:15:29 +00002424
2425 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002426 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002427 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002428
paul718e3742002-12-13 20:15:29 +00002429 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002430 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002431 {
pauld3241812003-09-29 12:42:39 +00002432 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2433 {
ajs2a42e282004-12-08 18:43:03 +00002434 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002435 inet_ntoa (iph->ip_src));
2436 }
paul718e3742002-12-13 20:15:29 +00002437 return 0;
2438 }
2439
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002440 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2441 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002442 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002443
2444 /* Make sure the OSPF header is really there. */
2445 if (stream_get_endp (ibuf) - stream_get_getp (ibuf) < OSPF_HEADER_SIZE)
2446 {
2447 zlog_debug ("ospf_read: ignored OSPF packet with undersized (%u bytes) header",
2448 stream_get_endp (ibuf) - stream_get_getp (ibuf));
2449 return -1;
2450 }
2451
2452 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002453 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2454
2455 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002456 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002457
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002458 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2459 after the passive/backbone/other checks below are passed. These checks
2460 in turn access the fields of unverified "ospfh" structure for their own
2461 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002462
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002463 /* If incoming interface is passive one, ignore it. */
2464 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2465 {
2466 char buf[3][INET_ADDRSTRLEN];
2467
2468 if (IS_DEBUG_OSPF_EVENT)
2469 zlog_debug ("ignoring packet from router %s sent to %s, "
2470 "received on a passive interface, %s",
2471 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2472 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2473 inet_ntop(AF_INET, &oi->address->u.prefix4,
2474 buf[2], sizeof(buf[2])));
2475
2476 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2477 {
2478 /* Try to fix multicast membership.
2479 * Some OS:es may have problems in this area,
2480 * make sure it is removed.
2481 */
2482 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2483 ospf_if_set_multicast(oi);
2484 }
2485 return 0;
2486 }
2487
2488
pauld3f0d622004-05-05 15:27:15 +00002489 /* if no local ospf_interface,
2490 * or header area is backbone but ospf_interface is not
2491 * check for VLINK interface
2492 */
2493 if ( (oi == NULL) ||
2494 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2495 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2496 )
2497 {
2498 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2499 {
Paul Jakma88871b12006-06-15 11:41:19 +00002500 if (IS_DEBUG_OSPF_EVENT)
2501 zlog_debug ("Packet from [%s] received on link %s"
2502 " but no ospf_interface",
2503 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002504 return 0;
2505 }
2506 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002507
pauld3f0d622004-05-05 15:27:15 +00002508 /* else it must be a local ospf interface, check it was received on
2509 * correct link
2510 */
2511 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002512 {
Paul Jakma11637432009-08-11 12:25:42 +01002513 if (IS_DEBUG_OSPF_EVENT)
2514 zlog_warn ("Packet from [%s] received on wrong link %s",
2515 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002516 return 0;
2517 }
ajs847947f2005-02-02 18:38:48 +00002518 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002519 {
ajsba6454e2005-02-08 15:37:30 +00002520 char buf[2][INET_ADDRSTRLEN];
2521 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002522 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002523 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2524 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2525 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002526 /* Fix multicast memberships? */
2527 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002528 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002529 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002530 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002531 if (oi->multicast_memberships)
2532 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002533 return 0;
2534 }
paul718e3742002-12-13 20:15:29 +00002535
2536 /*
2537 * If the received packet is destined for AllDRouters, the packet
2538 * should be accepted only if the received ospf interface state is
2539 * either DR or Backup -- endo.
2540 */
2541 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2542 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2543 {
ajsba6454e2005-02-08 15:37:30 +00002544 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002545 inet_ntoa (iph->ip_src), IF_NAME (oi),
2546 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002547 /* Try to fix multicast membership. */
2548 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2549 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002550 return 0;
2551 }
2552
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002553 /* Verify more OSPF header fields. */
2554 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2555 if (ret < 0)
2556 {
2557 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2558 zlog_debug ("ospf_read[%s]: Header check failed, "
2559 "dropping.",
2560 inet_ntoa (iph->ip_src));
2561 return ret;
2562 }
2563
paul718e3742002-12-13 20:15:29 +00002564 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002565 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2566 {
paul718e3742002-12-13 20:15:29 +00002567 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002568 {
ajs2a42e282004-12-08 18:43:03 +00002569 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002570 ospf_packet_dump (ibuf);
2571 }
paul718e3742002-12-13 20:15:29 +00002572
ajs2a42e282004-12-08 18:43:03 +00002573 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002574 ospf_packet_type_str[ospfh->type],
2575 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002576 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2577 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002578
2579 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002580 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002581 }
paul718e3742002-12-13 20:15:29 +00002582
paul9985f832005-02-09 15:51:56 +00002583 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002584
2585 /* Adjust size to message length. */
2586 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2587
2588 /* Read rest of the packet and call each sort of packet routine. */
2589 switch (ospfh->type)
2590 {
2591 case OSPF_MSG_HELLO:
2592 ospf_hello (iph, ospfh, ibuf, oi, length);
2593 break;
2594 case OSPF_MSG_DB_DESC:
2595 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2596 break;
2597 case OSPF_MSG_LS_REQ:
2598 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2599 break;
2600 case OSPF_MSG_LS_UPD:
2601 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2602 break;
2603 case OSPF_MSG_LS_ACK:
2604 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2605 break;
2606 default:
2607 zlog (NULL, LOG_WARNING,
2608 "interface %s: OSPF packet header type %d is illegal",
2609 IF_NAME (oi), ospfh->type);
2610 break;
2611 }
2612
paul718e3742002-12-13 20:15:29 +00002613 return 0;
2614}
2615
2616/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002617static void
paul718e3742002-12-13 20:15:29 +00002618ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2619{
2620 struct ospf_header *ospfh;
2621
2622 ospfh = (struct ospf_header *) STREAM_DATA (s);
2623
2624 ospfh->version = (u_char) OSPF_VERSION;
2625 ospfh->type = (u_char) type;
2626
paul68980082003-03-25 05:07:42 +00002627 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002628
2629 ospfh->checksum = 0;
2630 ospfh->area_id = oi->area->area_id;
2631 ospfh->auth_type = htons (ospf_auth_type (oi));
2632
2633 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2634
paul9985f832005-02-09 15:51:56 +00002635 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002636}
2637
2638/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002639static int
paul718e3742002-12-13 20:15:29 +00002640ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2641{
2642 struct crypt_key *ck;
2643
2644 switch (ospf_auth_type (oi))
2645 {
2646 case OSPF_AUTH_NULL:
2647 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2648 break;
2649 case OSPF_AUTH_SIMPLE:
2650 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2651 OSPF_AUTH_SIMPLE_SIZE);
2652 break;
2653 case OSPF_AUTH_CRYPTOGRAPHIC:
2654 /* If key is not set, then set 0. */
2655 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2656 {
2657 ospfh->u.crypt.zero = 0;
2658 ospfh->u.crypt.key_id = 0;
2659 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2660 }
2661 else
2662 {
paul1eb8ef22005-04-07 07:30:20 +00002663 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002664 ospfh->u.crypt.zero = 0;
2665 ospfh->u.crypt.key_id = ck->key_id;
2666 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2667 }
2668 /* note: the seq is done in ospf_make_md5_digest() */
2669 break;
2670 default:
2671 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2672 break;
2673 }
2674
2675 return 0;
2676}
2677
2678/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002679static void
paul718e3742002-12-13 20:15:29 +00002680ospf_fill_header (struct ospf_interface *oi,
2681 struct stream *s, u_int16_t length)
2682{
2683 struct ospf_header *ospfh;
2684
2685 ospfh = (struct ospf_header *) STREAM_DATA (s);
2686
2687 /* Fill length. */
2688 ospfh->length = htons (length);
2689
2690 /* Calculate checksum. */
2691 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2692 ospfh->checksum = in_cksum (ospfh, length);
2693 else
2694 ospfh->checksum = 0;
2695
2696 /* Add Authentication Data. */
2697 ospf_make_auth (oi, ospfh);
2698}
2699
paul4dadc292005-05-06 21:37:42 +00002700static int
paul718e3742002-12-13 20:15:29 +00002701ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2702{
2703 struct ospf_neighbor *nbr;
2704 struct route_node *rn;
2705 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2706 struct in_addr mask;
2707 unsigned long p;
2708 int flag = 0;
2709
2710 /* Set netmask of interface. */
2711 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2712 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2713 masklen2ip (oi->address->prefixlen, &mask);
2714 else
2715 memset ((char *) &mask, 0, sizeof (struct in_addr));
2716 stream_put_ipv4 (s, mask.s_addr);
2717
2718 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002719 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2720 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2721 else
2722 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002723
2724 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002725 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002726 OPTIONS(oi), IF_NAME (oi));
2727
2728 /* Set Options. */
2729 stream_putc (s, OPTIONS (oi));
2730
2731 /* Set Router Priority. */
2732 stream_putc (s, PRIORITY (oi));
2733
2734 /* Set Router Dead Interval. */
2735 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2736
2737 /* Set Designated Router. */
2738 stream_put_ipv4 (s, DR (oi).s_addr);
2739
paul9985f832005-02-09 15:51:56 +00002740 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002741
2742 /* Set Backup Designated Router. */
2743 stream_put_ipv4 (s, BDR (oi).s_addr);
2744
2745 /* Add neighbor seen. */
2746 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002747 if ((nbr = rn->info))
2748 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2749 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2750 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2751 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002752 {
2753 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002754 if (nbr->d_router.s_addr != 0
2755 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2756 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2757 flag = 1;
paul718e3742002-12-13 20:15:29 +00002758
2759 stream_put_ipv4 (s, nbr->router_id.s_addr);
2760 length += 4;
2761 }
2762
2763 /* Let neighbor generate BackupSeen. */
2764 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002765 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002766
2767 return length;
2768}
2769
paul4dadc292005-05-06 21:37:42 +00002770static int
paul718e3742002-12-13 20:15:29 +00002771ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2772 struct stream *s)
2773{
2774 struct ospf_lsa *lsa;
2775 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2776 u_char options;
2777 unsigned long pp;
2778 int i;
2779 struct ospf_lsdb *lsdb;
2780
2781 /* Set Interface MTU. */
2782 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2783 stream_putw (s, 0);
2784 else
2785 stream_putw (s, oi->ifp->mtu);
2786
2787 /* Set Options. */
2788 options = OPTIONS (oi);
2789#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002790 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002791 {
2792 if (IS_SET_DD_I (nbr->dd_flags)
2793 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2794 /*
2795 * Set O-bit in the outgoing DD packet for capablity negotiation,
2796 * if one of following case is applicable.
2797 *
2798 * 1) WaitTimer expiration event triggered the neighbor state to
2799 * change to Exstart, but no (valid) DD packet has received
2800 * from the neighbor yet.
2801 *
2802 * 2) At least one DD packet with O-bit on has received from the
2803 * neighbor.
2804 */
2805 SET_FLAG (options, OSPF_OPTION_O);
2806 }
2807#endif /* HAVE_OPAQUE_LSA */
2808 stream_putc (s, options);
2809
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002810 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002811 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002812 stream_putc (s, nbr->dd_flags);
2813
2814 /* Set DD Sequence Number. */
2815 stream_putl (s, nbr->dd_seqnum);
2816
Paul Jakmab5aeb442006-08-30 18:47:37 +00002817 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002818 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002819 goto empty;
paul718e3742002-12-13 20:15:29 +00002820
2821 /* Describe LSA Header from Database Summary List. */
2822 lsdb = &nbr->db_sum;
2823
2824 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2825 {
2826 struct route_table *table = lsdb->type[i].db;
2827 struct route_node *rn;
2828
2829 for (rn = route_top (table); rn; rn = route_next (rn))
2830 if ((lsa = rn->info) != NULL)
2831 {
2832#ifdef HAVE_OPAQUE_LSA
2833 if (IS_OPAQUE_LSA (lsa->data->type)
2834 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2835 {
2836 /* Suppress advertising opaque-informations. */
2837 /* Remove LSA from DB summary list. */
2838 ospf_lsdb_delete (lsdb, lsa);
2839 continue;
2840 }
2841#endif /* HAVE_OPAQUE_LSA */
2842
2843 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2844 {
2845 struct lsa_header *lsah;
2846 u_int16_t ls_age;
2847
2848 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002849 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002850 break;
2851
2852 /* Keep pointer to LS age. */
2853 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002854 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002855
2856 /* Proceed stream pointer. */
2857 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2858 length += OSPF_LSA_HEADER_SIZE;
2859
2860 /* Set LS age. */
2861 ls_age = LS_AGE (lsa);
2862 lsah->ls_age = htons (ls_age);
2863
2864 }
2865
2866 /* Remove LSA from DB summary list. */
2867 ospf_lsdb_delete (lsdb, lsa);
2868 }
2869 }
2870
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002871 /* Update 'More' bit */
2872 if (ospf_db_summary_isempty (nbr))
2873 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002874empty:
2875 if (nbr->state >= NSM_Exchange)
2876 {
2877 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2878 /* Rewrite DD flags */
2879 stream_putc_at (s, pp, nbr->dd_flags);
2880 }
2881 else
2882 {
2883 assert (IS_SET_DD_M(nbr->dd_flags));
2884 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002885 }
paul718e3742002-12-13 20:15:29 +00002886 return length;
2887}
2888
paul4dadc292005-05-06 21:37:42 +00002889static int
paul718e3742002-12-13 20:15:29 +00002890ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2891 unsigned long delta, struct ospf_neighbor *nbr,
2892 struct ospf_lsa *lsa)
2893{
2894 struct ospf_interface *oi;
2895
2896 oi = nbr->oi;
2897
2898 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002899 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002900 return 0;
2901
2902 stream_putl (s, lsa->data->type);
2903 stream_put_ipv4 (s, lsa->data->id.s_addr);
2904 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2905
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002906 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002907 nbr->ls_req_last = ospf_lsa_lock (lsa);
2908
2909 *length += 12;
2910 return 1;
2911}
2912
paul4dadc292005-05-06 21:37:42 +00002913static int
paul718e3742002-12-13 20:15:29 +00002914ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2915{
2916 struct ospf_lsa *lsa;
2917 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002918 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002919 struct route_table *table;
2920 struct route_node *rn;
2921 int i;
2922 struct ospf_lsdb *lsdb;
2923
2924 lsdb = &nbr->ls_req;
2925
2926 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2927 {
2928 table = lsdb->type[i].db;
2929 for (rn = route_top (table); rn; rn = route_next (rn))
2930 if ((lsa = (rn->info)) != NULL)
2931 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2932 {
2933 route_unlock_node (rn);
2934 break;
2935 }
2936 }
2937 return length;
2938}
2939
paul4dadc292005-05-06 21:37:42 +00002940static int
paul718e3742002-12-13 20:15:29 +00002941ls_age_increment (struct ospf_lsa *lsa, int delay)
2942{
2943 int age;
2944
2945 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2946
2947 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2948}
2949
paul4dadc292005-05-06 21:37:42 +00002950static int
hasso52dc7ee2004-09-23 19:18:23 +00002951ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002952{
2953 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002954 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002955 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00002956 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002957 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002958 unsigned long pp;
2959 int count = 0;
2960
2961 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002962 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002963
paul9985f832005-02-09 15:51:56 +00002964 pp = stream_get_endp (s);
2965 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002966 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00002967
gdt86f1fd92005-01-10 14:20:43 +00002968 /* Calculate amount of packet usable for data. */
2969 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2970
paul718e3742002-12-13 20:15:29 +00002971 while ((node = listhead (update)) != NULL)
2972 {
2973 struct lsa_header *lsah;
2974 u_int16_t ls_age;
2975
2976 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002977 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002978
paul1eb8ef22005-04-07 07:30:20 +00002979 lsa = listgetdata (node);
2980
paul718e3742002-12-13 20:15:29 +00002981 assert (lsa->data);
2982
paul68b73392004-09-12 14:21:37 +00002983 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002984 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002985 break;
2986
paul718e3742002-12-13 20:15:29 +00002987 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002988 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002989
2990 /* Put LSA to Link State Request. */
2991 stream_put (s, lsa->data, ntohs (lsa->data->length));
2992
2993 /* Set LS age. */
2994 /* each hop must increment an lsa_age by transmit_delay
2995 of OSPF interface */
2996 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2997 lsah->ls_age = htons (ls_age);
2998
2999 length += ntohs (lsa->data->length);
3000 count++;
3001
3002 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003003 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003004 }
3005
3006 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003007 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003008
3009 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003010 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003011 return length;
3012}
3013
paul4dadc292005-05-06 21:37:42 +00003014static int
hasso52dc7ee2004-09-23 19:18:23 +00003015ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003016{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003017 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003018 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003019 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003020 struct ospf_lsa *lsa;
3021
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003022 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003023 {
paul718e3742002-12-13 20:15:29 +00003024 assert (lsa);
3025
gdt86f1fd92005-01-10 14:20:43 +00003026 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003027 break;
3028
3029 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3030 length += OSPF_LSA_HEADER_SIZE;
3031
paul718e3742002-12-13 20:15:29 +00003032 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003033 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003034 }
3035
paul718e3742002-12-13 20:15:29 +00003036 return length;
3037}
3038
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003039static void
3040ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003041{
3042 struct ospf_packet *op;
3043 u_int16_t length = OSPF_HEADER_SIZE;
3044
3045 op = ospf_packet_new (oi->ifp->mtu);
3046
3047 /* Prepare OSPF common header. */
3048 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3049
3050 /* Prepare OSPF Hello body. */
3051 length += ospf_make_hello (oi, op->s);
3052
3053 /* Fill OSPF header. */
3054 ospf_fill_header (oi, op->s, length);
3055
3056 /* Set packet length. */
3057 op->length = length;
3058
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003059 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003060
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003061 /* Add packet to the top of the interface output queue, so that they
3062 * can't get delayed by things like long queues of LS Update packets
3063 */
3064 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003065
3066 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003067 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003068}
3069
paul4dadc292005-05-06 21:37:42 +00003070static void
paul718e3742002-12-13 20:15:29 +00003071ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3072{
3073 struct ospf_interface *oi;
3074
3075 oi = nbr_nbma->oi;
3076 assert(oi);
3077
3078 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003079 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003080 return;
3081
3082 if (oi->type != OSPF_IFTYPE_NBMA)
3083 return;
3084
3085 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3086 return;
3087
3088 if (PRIORITY(oi) == 0)
3089 return;
3090
3091 if (nbr_nbma->priority == 0
3092 && oi->state != ISM_DR && oi->state != ISM_Backup)
3093 return;
3094
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003095 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003096}
3097
3098int
3099ospf_poll_timer (struct thread *thread)
3100{
3101 struct ospf_nbr_nbma *nbr_nbma;
3102
3103 nbr_nbma = THREAD_ARG (thread);
3104 nbr_nbma->t_poll = NULL;
3105
3106 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003107 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003108 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3109
3110 ospf_poll_send (nbr_nbma);
3111
3112 if (nbr_nbma->v_poll > 0)
3113 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3114 nbr_nbma->v_poll);
3115
3116 return 0;
3117}
3118
3119
3120int
3121ospf_hello_reply_timer (struct thread *thread)
3122{
3123 struct ospf_neighbor *nbr;
3124
3125 nbr = THREAD_ARG (thread);
3126 nbr->t_hello_reply = NULL;
3127
3128 assert (nbr->oi);
3129
3130 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003131 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003132 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3133
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003134 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003135
3136 return 0;
3137}
3138
3139/* Send OSPF Hello. */
3140void
3141ospf_hello_send (struct ospf_interface *oi)
3142{
paul718e3742002-12-13 20:15:29 +00003143 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003144 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003145 return;
3146
paul718e3742002-12-13 20:15:29 +00003147 if (oi->type == OSPF_IFTYPE_NBMA)
3148 {
3149 struct ospf_neighbor *nbr;
3150 struct route_node *rn;
3151
3152 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3153 if ((nbr = rn->info))
3154 if (nbr != oi->nbr_self)
3155 if (nbr->state != NSM_Down)
3156 {
3157 /* RFC 2328 Section 9.5.1
3158 If the router is not eligible to become Designated Router,
3159 it must periodically send Hello Packets to both the
3160 Designated Router and the Backup Designated Router (if they
3161 exist). */
3162 if (PRIORITY(oi) == 0 &&
3163 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3164 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3165 continue;
3166
3167 /* If the router is eligible to become Designated Router, it
3168 must periodically send Hello Packets to all neighbors that
3169 are also eligible. In addition, if the router is itself the
3170 Designated Router or Backup Designated Router, it must also
3171 send periodic Hello Packets to all other neighbors. */
3172
3173 if (nbr->priority == 0 && oi->state == ISM_DROther)
3174 continue;
3175 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003176 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003177 }
paul718e3742002-12-13 20:15:29 +00003178 }
3179 else
3180 {
3181 /* Decide destination address. */
3182 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003183 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3184 else
3185 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003186 }
3187}
3188
3189/* Send OSPF Database Description. */
3190void
3191ospf_db_desc_send (struct ospf_neighbor *nbr)
3192{
3193 struct ospf_interface *oi;
3194 struct ospf_packet *op;
3195 u_int16_t length = OSPF_HEADER_SIZE;
3196
3197 oi = nbr->oi;
3198 op = ospf_packet_new (oi->ifp->mtu);
3199
3200 /* Prepare OSPF common header. */
3201 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3202
3203 /* Prepare OSPF Database Description body. */
3204 length += ospf_make_db_desc (oi, nbr, op->s);
3205
3206 /* Fill OSPF header. */
3207 ospf_fill_header (oi, op->s, length);
3208
3209 /* Set packet length. */
3210 op->length = length;
3211
3212 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003213 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3214 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3215 else
3216 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003217
3218 /* Add packet to the interface output queue. */
3219 ospf_packet_add (oi, op);
3220
3221 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003222 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003223
3224 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3225 if (nbr->last_send)
3226 ospf_packet_free (nbr->last_send);
3227 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003228 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003229}
3230
3231/* Re-send Database Description. */
3232void
3233ospf_db_desc_resend (struct ospf_neighbor *nbr)
3234{
3235 struct ospf_interface *oi;
3236
3237 oi = nbr->oi;
3238
3239 /* Add packet to the interface output queue. */
3240 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3241
3242 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003243 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003244}
3245
3246/* Send Link State Request. */
3247void
3248ospf_ls_req_send (struct ospf_neighbor *nbr)
3249{
3250 struct ospf_interface *oi;
3251 struct ospf_packet *op;
3252 u_int16_t length = OSPF_HEADER_SIZE;
3253
3254 oi = nbr->oi;
3255 op = ospf_packet_new (oi->ifp->mtu);
3256
3257 /* Prepare OSPF common header. */
3258 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3259
3260 /* Prepare OSPF Link State Request body. */
3261 length += ospf_make_ls_req (nbr, op->s);
3262 if (length == OSPF_HEADER_SIZE)
3263 {
3264 ospf_packet_free (op);
3265 return;
3266 }
3267
3268 /* Fill OSPF header. */
3269 ospf_fill_header (oi, op->s, length);
3270
3271 /* Set packet length. */
3272 op->length = length;
3273
3274 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003275 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3276 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3277 else
3278 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003279
3280 /* Add packet to the interface output queue. */
3281 ospf_packet_add (oi, op);
3282
3283 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003284 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003285
3286 /* Add Link State Request Retransmission Timer. */
3287 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3288}
3289
3290/* Send Link State Update with an LSA. */
3291void
3292ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3293 int flag)
3294{
hasso52dc7ee2004-09-23 19:18:23 +00003295 struct list *update;
paul718e3742002-12-13 20:15:29 +00003296
3297 update = list_new ();
3298
3299 listnode_add (update, lsa);
3300 ospf_ls_upd_send (nbr, update, flag);
3301
3302 list_delete (update);
3303}
3304
paul68b73392004-09-12 14:21:37 +00003305/* Determine size for packet. Must be at least big enough to accomodate next
3306 * LSA on list, which may be bigger than MTU size.
3307 *
3308 * Return pointer to new ospf_packet
3309 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3310 * on packet sizes (in which case offending LSA is deleted from update list)
3311 */
3312static struct ospf_packet *
3313ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3314{
3315 struct ospf_lsa *lsa;
3316 struct listnode *ln;
3317 size_t size;
3318 static char warned = 0;
3319
paul1eb8ef22005-04-07 07:30:20 +00003320 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003321 assert (lsa->data);
3322
3323 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3324 > ospf_packet_max (oi))
3325 {
3326 if (!warned)
3327 {
3328 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3329 "will need to fragment. Not optimal. Try divide up"
3330 " your network with areas. Use 'debug ospf packet send'"
3331 " to see details, or look at 'show ip ospf database ..'");
3332 warned = 1;
3333 }
3334
3335 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003336 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003337 " %d bytes originated by %s, will be fragmented!",
3338 inet_ntoa (lsa->data->id),
3339 ntohs (lsa->data->length),
3340 inet_ntoa (lsa->data->adv_router));
3341
3342 /*
3343 * Allocate just enough to fit this LSA only, to avoid including other
3344 * LSAs in fragmented LSA Updates.
3345 */
3346 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3347 + OSPF_LS_UPD_MIN_SIZE;
3348 }
3349 else
3350 size = oi->ifp->mtu;
3351
3352 if (size > OSPF_MAX_PACKET_SIZE)
3353 {
3354 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003355 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003356 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003357 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003358 (long int) size);
paul68b73392004-09-12 14:21:37 +00003359 list_delete_node (update, ln);
3360 return NULL;
3361 }
3362
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003363 /* IP header is built up separately by ospf_write(). This means, that we must
3364 * reduce the "affordable" size just calculated by length of an IP header.
3365 * This makes sure, that even if we manage to fill the payload with LSA data
3366 * completely, the final packet (our data plus IP header) still fits into
3367 * outgoing interface MTU. This correction isn't really meaningful for an
3368 * oversized LSA, but for consistency the correction is done for both cases.
3369 *
3370 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3371 */
3372 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003373}
3374
paul718e3742002-12-13 20:15:29 +00003375static void
hasso52dc7ee2004-09-23 19:18:23 +00003376ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003377 struct in_addr addr)
3378{
3379 struct ospf_packet *op;
3380 u_int16_t length = OSPF_HEADER_SIZE;
3381
3382 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003383 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003384
3385 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003386
3387 /* Prepare OSPF common header. */
3388 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3389
paul59ea14c2004-07-14 20:50:36 +00003390 /* Prepare OSPF Link State Update body.
3391 * Includes Type-7 translation.
3392 */
paul718e3742002-12-13 20:15:29 +00003393 length += ospf_make_ls_upd (oi, update, op->s);
3394
3395 /* Fill OSPF header. */
3396 ospf_fill_header (oi, op->s, length);
3397
3398 /* Set packet length. */
3399 op->length = length;
3400
3401 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003402 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3403 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3404 else
3405 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003406
3407 /* Add packet to the interface output queue. */
3408 ospf_packet_add (oi, op);
3409
3410 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003411 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003412}
3413
3414static int
3415ospf_ls_upd_send_queue_event (struct thread *thread)
3416{
3417 struct ospf_interface *oi = THREAD_ARG(thread);
3418 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003419 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003420 struct list *update;
paul68b73392004-09-12 14:21:37 +00003421 char again = 0;
paul718e3742002-12-13 20:15:29 +00003422
3423 oi->t_ls_upd_event = NULL;
3424
3425 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003426 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003427
paul736d3442003-07-24 23:22:57 +00003428 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003429 {
paul736d3442003-07-24 23:22:57 +00003430 rnext = route_next (rn);
3431
paul718e3742002-12-13 20:15:29 +00003432 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003433 continue;
paul68b73392004-09-12 14:21:37 +00003434
3435 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003436
paul48fe13b2004-07-27 17:40:44 +00003437 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003438
paul68b73392004-09-12 14:21:37 +00003439 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003440 if (listcount(update) == 0)
3441 {
3442 list_delete (rn->info);
3443 rn->info = NULL;
3444 route_unlock_node (rn);
3445 }
3446 else
paul68b73392004-09-12 14:21:37 +00003447 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003448 }
3449
3450 if (again != 0)
3451 {
3452 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003453 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003454 " %d nodes to try again, raising new event", again);
3455 oi->t_ls_upd_event =
3456 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003457 }
3458
3459 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003460 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003461
paul718e3742002-12-13 20:15:29 +00003462 return 0;
3463}
3464
3465void
hasso52dc7ee2004-09-23 19:18:23 +00003466ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003467{
3468 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003469 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003470 struct prefix_ipv4 p;
3471 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003472 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003473
3474 oi = nbr->oi;
3475
3476 p.family = AF_INET;
3477 p.prefixlen = IPV4_MAX_BITLEN;
3478
3479 /* Decide destination address. */
3480 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3481 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003482 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3483 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003484 else if (flag == OSPF_SEND_PACKET_DIRECT)
3485 p.prefix = nbr->address.u.prefix4;
3486 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3487 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003488 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3489 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003490 else
3491 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3492
3493 if (oi->type == OSPF_IFTYPE_NBMA)
3494 {
3495 if (flag == OSPF_SEND_PACKET_INDIRECT)
3496 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3497 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3498 zlog_warn ("* LS-Update is sent to myself.");
3499 }
3500
3501 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3502
3503 if (rn->info == NULL)
3504 rn->info = list_new ();
3505
paul1eb8ef22005-04-07 07:30:20 +00003506 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003507 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003508
3509 if (oi->t_ls_upd_event == NULL)
3510 oi->t_ls_upd_event =
3511 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3512}
3513
3514static void
hasso52dc7ee2004-09-23 19:18:23 +00003515ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3516 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003517{
3518 struct ospf_packet *op;
3519 u_int16_t length = OSPF_HEADER_SIZE;
3520
3521 op = ospf_packet_new (oi->ifp->mtu);
3522
3523 /* Prepare OSPF common header. */
3524 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3525
3526 /* Prepare OSPF Link State Acknowledgment body. */
3527 length += ospf_make_ls_ack (oi, ack, op->s);
3528
3529 /* Fill OSPF header. */
3530 ospf_fill_header (oi, op->s, length);
3531
3532 /* Set packet length. */
3533 op->length = length;
3534
3535 /* Set destination IP address. */
3536 op->dst = dst;
3537
3538 /* Add packet to the interface output queue. */
3539 ospf_packet_add (oi, op);
3540
3541 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003542 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003543}
3544
3545static int
3546ospf_ls_ack_send_event (struct thread *thread)
3547{
3548 struct ospf_interface *oi = THREAD_ARG (thread);
3549
3550 oi->t_ls_ack_direct = NULL;
3551
3552 while (listcount (oi->ls_ack_direct.ls_ack))
3553 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3554 oi->ls_ack_direct.dst);
3555
3556 return 0;
3557}
3558
3559void
3560ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3561{
3562 struct ospf_interface *oi = nbr->oi;
3563
3564 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3565 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3566
3567 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3568
3569 if (oi->t_ls_ack_direct == NULL)
3570 oi->t_ls_ack_direct =
3571 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3572}
3573
3574/* Send Link State Acknowledgment delayed. */
3575void
3576ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3577{
3578 struct in_addr dst;
3579
3580 /* Decide destination address. */
3581 /* RFC2328 Section 13.5 On non-broadcast
3582 networks, delayed Link State Acknowledgment packets must be
3583 unicast separately over each adjacency (i.e., neighbor whose
3584 state is >= Exchange). */
3585 if (oi->type == OSPF_IFTYPE_NBMA)
3586 {
3587 struct ospf_neighbor *nbr;
3588 struct route_node *rn;
3589
3590 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3591 if ((nbr = rn->info) != NULL)
3592 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3593 while (listcount (oi->ls_ack))
3594 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3595 return;
3596 }
3597 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3598 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3599 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3600 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3601 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3602 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003603 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3604 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003605 else
3606 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3607
3608 while (listcount (oi->ls_ack))
3609 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3610}