]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_packet.c
doc: Fix an apparently no longer legal @itemize @asis
[mirror_frr.git] / ospfd / ospf_packet.c
CommitLineData
718e3744 1/*
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"
2dd8bb4e 34#include "sockopt.h"
484315fd 35#include "checksum.h"
c1a03d47 36#include "md5.h"
718e3744 37
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
718e3744 52/* Packet Type String. */
eb1ce605 53const char *ospf_packet_type_str[] =
718e3744 54{
55 "unknown",
56 "Hello",
57 "Database Description",
58 "Link State Request",
59 "Link State Update",
60 "Link State Acknowledgment",
61};
62
718e3744 63/* OSPF authentication checking function */
4dadc291 64static int
718e3744 65ospf_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
718e3744 83struct 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
aa276fd7
PJ
128/* 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
718e3744 142/* 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{
c3eab871 198 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
718e3744 209 /* 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
aa276fd7
PJ
216static 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
718e3744 237void
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
718e3744 248struct ospf_packet *
249ospf_packet_dup (struct ospf_packet *op)
250{
251 struct ospf_packet *new;
252
37163d6d 253 if (stream_get_endp(op->s) != op->length)
08c83671
AS
254 /* 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);
30961a15 257
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);
fa81b713 260 stream_copy (new->s, op->s);
718e3744 261
262 new->dst = op->dst;
263 new->length = op->length;
264
265 return new;
266}
267
86f1fd96 268/* XXX inline */
f63f06da 269static unsigned int
86f1fd96 270ospf_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
4dadc291 280static unsigned int
718e3744 281ospf_packet_max (struct ospf_interface *oi)
282{
283 int max;
284
86f1fd96 285 max = oi->ifp->mtu - ospf_packet_authspace(oi);
286
68b7339a 287 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
718e3744 288
289 return max;
290}
291
292\f
4dadc291 293static int
718e3744 294ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
295 u_int16_t length)
296{
6c835671 297 unsigned char *ibuf;
c1a03d47 298 MD5_CTX ctx;
718e3744 299 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. */
c1a03d47 335 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);
718e3744 340
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. */
4dadc291 358static int
718e3744 359ospf_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];
c1a03d47 363 MD5_CTX ctx;
718e3744 364 void *ibuf;
9483e155 365 u_int32_t t;
718e3744 366 struct crypt_key *ck;
3623814a 367 const u_int8_t *auth_key;
718e3744 368
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
2518efd1
PJ
376 waste CPU rewriting other headers.
377
378 Note that quagga_time /deliberately/ is not used here */
9483e155 379 t = (time(NULL) & 0xFFFFFFFF);
818e56cf 380 if (t > oi->crypt_seqnum)
381 oi->crypt_seqnum = t;
382 else
383 oi->crypt_seqnum++;
384
9483e155 385 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
718e3744 386
387 /* Get MD5 Authentication key from auth_key list. */
388 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
3623814a 389 auth_key = (const u_int8_t *) "";
718e3744 390 else
391 {
1eb8ef25 392 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
4dadc291 393 auth_key = ck->auth_key;
718e3744 394 }
395
396 /* Generate a digest for the entire packet + our secret key. */
c1a03d47 397 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);
718e3744 402
403 /* Append md5 digest to the end of the stream. */
718e3744 404 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
718e3744 405
406 /* We do *NOT* increment the OSPF header length. */
30961a15 407 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
408
37163d6d 409 if (stream_get_endp(op->s) != op->length)
08c83671
AS
410 /* 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);
718e3744 413
414 return OSPF_AUTH_MD5_SIZE;
415}
416
417\f
4dadc291 418static int
718e3744 419ospf_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 {
52dc7ee6 460 struct list *update;
718e3744 461 struct ospf_lsdb *lsdb;
462 int i;
718e3744 463 int retransmit_interval;
464
718e3744 465 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 */
2518efd1 487 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
718e3744 488 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
0bfeca3f 522#ifdef WANT_OSPF_WRITE_FRAGMENT
5dcbdf82 523static void
6a99f831 524ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
62d8e96a 525 struct msghdr *msg, unsigned int maxdatasize,
37ccfa3d 526 unsigned int mtu, int flags, u_char type)
0bfeca3f 527{
528#define OSPF_WRITE_FRAG_SHIFT 3
6a99f831 529 u_int16_t offset;
62d8e96a 530 struct iovec *iovp;
6a99f831 531 int ret;
0bfeca3f 532
533 assert ( op->length == stream_get_endp(op->s) );
62d8e96a 534 assert (msg->msg_iovlen == 2);
0bfeca3f 535
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
62d8e96a 556 iovp = &msg->msg_iov[1];
557
0bfeca3f 558 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 */
62d8e96a 562 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
563 iph->ip_len = iovp->iov_len + sizeof (struct ip);
6a99f831 564 assert (iph->ip_len <= mtu);
0bfeca3f 565
18b12c38 566 sockopt_iphdrincl_swab_htosys (iph);
0bfeca3f 567
6a99f831 568 ret = sendmsg (fd, msg, flags);
0bfeca3f 569
18b12c38 570 sockopt_iphdrincl_swab_systoh (iph);
0bfeca3f 571
572 if (ret < 0)
37ccfa3d 573 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
5dcbdf82 574 " 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));
0bfeca3f 581
37ccfa3d 582 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
583 {
2a42e285 584 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
37ccfa3d 585 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 {
2a42e285 589 zlog_debug ("-----------------IP Header Dump----------------------");
37ccfa3d 590 ospf_ip_header_dump (iph);
2a42e285 591 zlog_debug ("-----------------------------------------------------");
37ccfa3d 592 }
593 }
594
0bfeca3f 595 iph->ip_off += offset;
9985f83c 596 stream_forward_getp (op->s, iovp->iov_len);
62d8e96a 597 iovp->iov_base = STREAM_PNT (op->s);
0bfeca3f 598 }
599
600 /* setup for final fragment */
62d8e96a 601 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
602 iph->ip_len = iovp->iov_len + sizeof (struct ip);
0bfeca3f 603 iph->ip_off &= (~IP_MF);
604}
605#endif /* WANT_OSPF_WRITE_FRAGMENT */
606
5dcbdf82 607static int
718e3744 608ospf_write (struct thread *thread)
609{
68980084 610 struct ospf *ospf = THREAD_ARG (thread);
718e3744 611 struct ospf_interface *oi;
612 struct ospf_packet *op;
613 struct sockaddr_in sa_dst;
718e3744 614 struct ip iph;
615 struct msghdr msg;
62d8e96a 616 struct iovec iov[2];
68980084 617 u_char type;
618 int ret;
619 int flags = 0;
52dc7ee6 620 struct listnode *node;
0bfeca3f 621#ifdef WANT_OSPF_WRITE_FRAGMENT
68b7339a 622 static u_int16_t ipid = 0;
0bfeca3f 623#endif /* WANT_OSPF_WRITE_FRAGMENT */
6a99f831 624 u_int16_t maxdatasize;
68b7339a 625#define OSPF_WRITE_IPHL_SHIFT 2
718e3744 626
68980084 627 ospf->t_write = NULL;
718e3744 628
68980084 629 node = listhead (ospf->oi_write_q);
718e3744 630 assert (node);
1eb8ef25 631 oi = listgetdata (node);
718e3744 632 assert (oi);
0bfeca3f 633
634#ifdef WANT_OSPF_WRITE_FRAGMENT
68b7339a 635 /* seed ipid static with low order bits of time */
636 if (ipid == 0)
637 ipid = (time(NULL) & 0xffff);
0bfeca3f 638#endif /* WANT_OSPF_WRITE_FRAGMENT */
639
b7fe4141
DO
640 /* 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);
68b7339a 646
718e3744 647 /* Get one packet from queue. */
648 op = ospf_fifo_head (oi->obuf);
649 assert (op);
650 assert (op->length >= OSPF_HEADER_SIZE);
651
68980084 652 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
653 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
68b7339a 654 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
655
718e3744 656 /* Rewrite the md5 signature & update the seq */
657 ospf_make_md5_digest (oi, op);
658
37ccfa3d 659 /* Retrieve OSPF packet type. */
660 stream_set_getp (op->s, 1);
661 type = stream_getc (op->s);
662
68b7339a 663 /* reset get pointer */
664 stream_set_getp (op->s, 0);
665
666 memset (&iph, 0, sizeof (struct ip));
718e3744 667 memset (&sa_dst, 0, sizeof (sa_dst));
68b7339a 668
718e3744 669 sa_dst.sin_family = AF_INET;
6f0e3f6e 670#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
718e3744 671 sa_dst.sin_len = sizeof(sa_dst);
6f0e3f6e 672#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
718e3744 673 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
68b7339a 681 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.. */
6c835671 683 if ( sizeof (struct ip)
684 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
68b7339a 685 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
686
718e3744 687 iph.ip_v = IPVERSION;
68980084 688 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
68b7339a 689 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
68b7339a 690
0150c9c9
DB
691#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
0bfeca3f 698#ifdef WANT_OSPF_WRITE_FRAGMENT
68b7339a 699 /* 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;
0bfeca3f 704#endif /* WANT_OSPF_WRITE_FRAGMENT */
705
718e3744 706 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));
68defd6d 717 msg.msg_name = (caddr_t) &sa_dst;
718e3744 718 msg.msg_namelen = sizeof (sa_dst);
719 msg.msg_iov = iov;
720 msg.msg_iovlen = 2;
721 iov[0].iov_base = (char*)&iph;
68b7339a 722 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
723 iov[1].iov_base = STREAM_PNT (op->s);
718e3744 724 iov[1].iov_len = op->length;
68b7339a 725
726 /* Sadly we can not rely on kernels to fragment packets because of either
727 * IP_HDRINCL and/or multicast destination being set.
728 */
0bfeca3f 729#ifdef WANT_OSPF_WRITE_FRAGMENT
68b7339a 730 if ( op->length > maxdatasize )
62d8e96a 731 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
732 oi->ifp->mtu, flags, type);
0bfeca3f 733#endif /* WANT_OSPF_WRITE_FRAGMENT */
718e3744 734
68b7339a 735 /* send final fragment (could be first) */
18b12c38 736 sockopt_iphdrincl_swab_htosys (&iph);
68980084 737 ret = sendmsg (ospf->fd, &msg, flags);
6b333611 738 sockopt_iphdrincl_swab_systoh (&iph);
718e3744 739
740 if (ret < 0)
083ee9d9 741 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
5dcbdf82 742 "id %d, off %d, len %d, interface %s, mtu %u: %s",
083ee9d9 743 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
5dcbdf82 744 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
718e3744 745
718e3744 746 /* Show debug sending packet. */
747 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
748 {
749 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
750 {
2a42e285 751 zlog_debug ("-----------------------------------------------------");
37ccfa3d 752 ospf_ip_header_dump (&iph);
718e3744 753 stream_set_getp (op->s, 0);
754 ospf_packet_dump (op->s);
755 }
756
2a42e285 757 zlog_debug ("%s sent to [%s] via [%s].",
718e3744 758 ospf_packet_type_str[type], inet_ntoa (op->dst),
759 IF_NAME (oi));
760
761 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
2a42e285 762 zlog_debug ("-----------------------------------------------------");
718e3744 763 }
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;
68980084 771 list_delete_node (ospf->oi_write_q, node);
718e3744 772 }
773
774 /* If packets still remain in queue, call write thread. */
68980084 775 if (!list_isempty (ospf->oi_write_q))
776 ospf->t_write =
777 thread_add_write (master, ospf_write, ospf, ospf->fd);
718e3744 778
779 return 0;
780}
781
782/* OSPF Hello message read -- RFC2328 Section 10.5. */
4dadc291 783static void
718e3744 784ospf_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;
718e3744 789 int old_state;
d3f0d621 790 struct prefix p;
718e3744 791
792 /* increment statistics. */
793 oi->hello_in++;
794
795 hello = (struct ospf_hello *) STREAM_PNT (s);
796
797 /* If Hello is myself, silently discard. */
68980084 798 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
d324181c 799 {
800 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
801 {
2a42e285 802 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
d324181c 803 "dropping.",
804 ospf_packet_type_str[ospfh->type],
805 inet_ntoa (iph->ip_src));
806 }
807 return;
808 }
718e3744 809
718e3744 810 /* 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 {
13cd3dc1
AS
821 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);
718e3744 824 return;
825 }
826
718e3744 827 /* Compare Router Dead Interval. */
828 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
829 {
08c83671
AS
830 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));
718e3744 834 return;
835 }
836
f9ad937f 837 /* 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 {
08c83671
AS
842 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));
f9ad937f 846 return;
847 }
848 }
849
718e3744 850 if (IS_DEBUG_OSPF_EVENT)
2a42e285 851 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
718e3744 852 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
68980084 871 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
718e3744 872 && 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
718e3744 890 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)
2a42e285 901 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
718e3744 902 }
903 else
718e3744 904 /* 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 {
3aa8d5f9 912 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
913 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
718e3744 914 return;
915 }
718e3744 916
d3f0d621 917 /* 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);
718e3744 922
923 old_state = nbr->state;
924
925 /* Add event to thread. */
57c5c652 926 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
718e3744 927
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 {
57c5c652 946 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
718e3744 947 nbr->priority = hello->priority;
948 nbr->d_router = hello->d_router;
949 nbr->bd_router = hello->bd_router;
950 return;
951 }
952
68980084 953 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
718e3744 954 size - OSPF_HELLO_MIN_SIZE))
955 {
57c5c652 956 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
718e3744 957 nbr->options |= hello->options;
958 }
959 else
960 {
57c5c652 961 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
718e3744 962 /* 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. */
4dadc291 1005static void
718e3744 1006ospf_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
9985f83c 1023 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
718e3744 1024 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);
9985f83c 1028 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
718e3744 1029
1030 /* Unknown LS type. */
1031 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1032 {
bec595ad 1033 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
718e3744 1034 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 */
718e3744 1054 /* 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)
718e3744 1057 {
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);
f0894cf8
PJ
1075
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 }
718e3744 1109 }
1110
1111 /* Master */
1112 if (IS_SET_DD_MS (nbr->dd_flags))
1113 {
1114 nbr->dd_seqnum++;
8dd24ee6
PJ
1115
1116 /* Both sides have no More, then we're done with Exchange */
718e3744 1117 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1118 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1119 else
718e3744 1120 ospf_db_desc_send (nbr);
1121 }
1122 /* Slave */
1123 else
1124 {
1125 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1126
8dd24ee6
PJ
1127 /* 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 */
718e3744 1135 ospf_db_desc_send (nbr);
8dd24ee6
PJ
1136
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);
718e3744 1140 }
8dd24ee6 1141
718e3744 1142 /* Save received neighbor values from DD. */
1143 ospf_db_desc_save_current (nbr, dd);
1144}
1145
4dadc291 1146static int
718e3744 1147ospf_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. */
3aa8d5f9 1159static void
718e3744 1160ospf_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);
d363df2c 1170
d3f0d621 1171 nbr = ospf_nbr_lookup (oi, iph, ospfh);
718e3744 1172 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. */
ba682537 1180 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1181 (ntohs (dd->mtu) > oi->ifp->mtu))
718e3744 1182 {
3aa8d5f9 1183 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);
718e3744 1186 return;
1187 }
1188
d363df2c 1189 /*
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)
1210fa66 1207 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
d363df2c 1208 inet_ntoa (nbr->router_id) );
1209 SET_FLAG (dd->options, OSPF_OPTION_NP);
1210 }
d363df2c 1211
718e3744 1212#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)
68980084 1226 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
718e3744 1227 {
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
57c5c652
PJ
1236 /* Add event to thread. */
1237 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1238
718e3744 1239 /* Process DD packet by neighbor status. */
1240 switch (nbr->state)
1241 {
1242 case NSM_Down:
1243 case NSM_Attempt:
1244 case NSM_TwoWay:
bec595ad 1245 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
3aa8d5f9 1246 inet_ntoa(nbr->router_id),
718e3744 1247 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 {
68980084 1261 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
718e3744 1262 {
1263 /* We're Slave---obey */
17eaa728 1264 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
3aa8d5f9 1265 inet_ntoa(nbr->router_id));
718e3744 1266 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
8dd24ee6
PJ
1267
1268 /* Reset I/MS */
1269 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
718e3744 1270 }
1271 else
1272 {
1273 /* We're Master, ignore the initial DBD from Slave */
6d45276f 1274 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
3aa8d5f9 1275 "ignoring.", inet_ntoa(nbr->router_id));
718e3744 1276 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 &&
68980084 1282 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
718e3744 1283 {
17eaa728 1284 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
3aa8d5f9 1285 inet_ntoa(nbr->router_id));
8dd24ee6
PJ
1286 /* Reset I, leaving MS */
1287 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
718e3744 1288 }
1289 else
1290 {
3aa8d5f9 1291 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1292 inet_ntoa(nbr->router_id));
718e3744 1293 break;
1294 }
1295
1296 /* This is where the real Options are saved */
1297 nbr->options = dd->options;
1298
1299#ifdef HAVE_OPAQUE_LSA
68980084 1300 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
718e3744 1301 {
1302 if (IS_DEBUG_OSPF_EVENT)
2a42e285 1303 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
718e3744 1304 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 {
6d45276f 1310 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));
718e3744 1314 /* 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. */
6d45276f 1329 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
3aa8d5f9 1330 inet_ntoa (nbr->router_id));
718e3744 1331 else
1332 /* Slave: cause to retransmit the last Database Description. */
1333 {
6d45276f 1334 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
3aa8d5f9 1335 inet_ntoa (nbr->router_id));
718e3744 1336 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 {
3aa8d5f9 1345 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1346 inet_ntoa(nbr->router_id));
718e3744 1347 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1348 if (IS_DEBUG_OSPF_EVENT)
2a42e285 1349 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
3aa8d5f9 1350 dd->flags, nbr->dd_flags);
718e3744 1351 break;
1352 }
1353
1354 /* Check initialize bit is set. */
1355 if (IS_SET_DD_I (dd->flags))
1356 {
6d45276f 1357 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
3aa8d5f9 1358 inet_ntoa(nbr->router_id));
718e3744 1359 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 */
3aa8d5f9 1370 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1371 inet_ntoa(nbr->router_id));
718e3744 1372 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 {
3aa8d5f9 1382 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1383 inet_ntoa(nbr->router_id));
718e3744 1384 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. */
6d45276f 1398 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1399 "packet discarded.",
3aa8d5f9 1400 inet_ntoa(nbr->router_id));
718e3744 1401 break;
1402 }
1403 else
1404 {
1405 struct timeval t, now;
2518efd1 1406 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
718e3744 1407 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:
3aa8d5f9 1428 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1429 inet_ntoa(nbr->router_id), nbr->state);
718e3744 1430 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. */
4dadc291 1437static void
718e3744 1438ospf_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;
52dc7ee6 1446 struct list *ls_upd;
6c835671 1447 unsigned int length;
718e3744 1448
1449 /* Increment statistics. */
1450 oi->ls_req_in++;
1451
d3f0d621 1452 nbr = ospf_nbr_lookup (oi, iph, ospfh);
718e3744 1453 if (nbr == NULL)
1454 {
1455 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1456 inet_ntoa (ospfh->router_id));
1457 return;
1458 }
1459
57c5c652
PJ
1460 /* Add event to thread. */
1461 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1462
718e3744 1463 /* Neighbor State should be Exchange or later. */
1464 if (nbr->state != NSM_Exchange &&
1465 nbr->state != NSM_Loading &&
1466 nbr->state != NSM_Full)
1467 {
bec595ad 1468 zlog_warn ("Link State Request received from %s: "
1469 "Neighbor state is %s, packet discarded.",
1470 inet_ntoa (ospfh->router_id),
718e3744 1471 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
86f1fd96 1503 /* Packet overflows MTU size, send immediately. */
1504 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
718e3744 1505 {
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). */
52dc7ee6 1540static struct list *
718e3744 1541ospf_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;
52dc7ee6 1548 struct list *lsas;
718e3744 1549
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;
9985f83c 1556 size -= length, stream_forward_getp (s, length), count--)
718e3744 1557 {
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 {
223da1a9
JF
1571 /* (bug #685) more details in a one-line message make it possible
1572 * to identify problem source on the one hand and to have a better
1573 * chance to compress repeated messages in syslog on the other */
1574 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1575 sum, lsah->checksum, inet_ntoa (lsah->id),
1576 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1577 inet_ntoa (lsah->adv_router));
718e3744 1578 continue;
1579 }
1580
1581 /* Examine the LSA's LS type. */
1582 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1583 {
1584 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1585 continue;
1586 }
1587
1588 /*
1589 * What if the received LSA's age is greater than MaxAge?
1590 * Treat it as a MaxAge case -- endo.
1591 */
1592 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1593 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1594
1595#ifdef HAVE_OPAQUE_LSA
1596 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1597 {
1598#ifdef STRICT_OBIT_USAGE_CHECK
1599 if ((IS_OPAQUE_LSA(lsah->type) &&
1600 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1601 || (! IS_OPAQUE_LSA(lsah->type) &&
1602 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1603 {
1604 /*
1605 * This neighbor must know the exact usage of O-bit;
1606 * the bit will be set in Type-9,10,11 LSAs only.
1607 */
1608 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1609 continue;
1610 }
1611#endif /* STRICT_OBIT_USAGE_CHECK */
1612
1613 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1614 if (lsah->type == OSPF_OPAQUE_AS_LSA
1615 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1616 {
1617 if (IS_DEBUG_OSPF_EVENT)
2a42e285 1618 zlog_debug ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
718e3744 1619 continue;
1620 }
1621 }
1622 else if (IS_OPAQUE_LSA(lsah->type))
1623 {
1624 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1625 continue;
1626 }
1627#endif /* HAVE_OPAQUE_LSA */
1628
1629 /* Create OSPF LSA instance. */
1630 lsa = ospf_lsa_new ();
1631
1632 /* We may wish to put some error checking if type NSSA comes in
1633 and area not in NSSA mode */
1634 switch (lsah->type)
1635 {
1636 case OSPF_AS_EXTERNAL_LSA:
1637#ifdef HAVE_OPAQUE_LSA
1638 case OSPF_OPAQUE_AS_LSA:
1639 lsa->area = NULL;
1640 break;
1641 case OSPF_OPAQUE_LINK_LSA:
1642 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1643 /* Fallthrough */
1644#endif /* HAVE_OPAQUE_LSA */
1645 default:
1646 lsa->area = oi->area;
1647 break;
1648 }
1649
1650 lsa->data = ospf_lsa_data_new (length);
1651 memcpy (lsa->data, lsah, length);
1652
1653 if (IS_DEBUG_OSPF_EVENT)
2a42e285 1654 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
718e3744 1655 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1656 listnode_add (lsas, lsa);
1657 }
1658
1659 return lsas;
1660}
1661
1662/* Cleanup Update list. */
4dadc291 1663static void
52dc7ee6 1664ospf_upd_list_clean (struct list *lsas)
718e3744 1665{
1eb8ef25 1666 struct listnode *node, *nnode;
718e3744 1667 struct ospf_lsa *lsa;
1668
1eb8ef25 1669 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1670 ospf_lsa_discard (lsa);
718e3744 1671
1672 list_delete (lsas);
1673}
1674
1675/* OSPF Link State Update message read -- RFC2328 Section 13. */
4dadc291 1676static void
718e3744 1677ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1678 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1679{
1680 struct ospf_neighbor *nbr;
52dc7ee6 1681 struct list *lsas;
1eb8ef25 1682 struct listnode *node, *nnode;
718e3744 1683 struct ospf_lsa *lsa = NULL;
1684 /* unsigned long ls_req_found = 0; */
1685
1686 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1687
1688 /* Increment statistics. */
1689 oi->ls_upd_in++;
1690
1691 /* Check neighbor. */
d3f0d621 1692 nbr = ospf_nbr_lookup (oi, iph, ospfh);
718e3744 1693 if (nbr == NULL)
1694 {
1695 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1696 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1697 return;
1698 }
1699
57c5c652
PJ
1700 /* Add event to thread. */
1701 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1702
718e3744 1703 /* Check neighbor state. */
1704 if (nbr->state < NSM_Exchange)
1705 {
3aa8d5f9 1706 zlog_warn ("Link State Update: "
1707 "Neighbor[%s] state %s is less than Exchange",
1708 inet_ntoa (ospfh->router_id),
1709 LOOKUP(ospf_nsm_state_msg, nbr->state));
718e3744 1710 return;
1711 }
1712
1713 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1714 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1715 * of section 13.
1716 */
1717 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1718
1719#ifdef HAVE_OPAQUE_LSA
718e3744 1720 /*
1721 * If self-originated Opaque-LSAs that have flooded before restart
1722 * are contained in the received LSUpd message, corresponding LSReq
1723 * messages to be sent may have to be modified.
1724 * To eliminate possible race conditions such that flushing and normal
1725 * updating for the same LSA would take place alternately, this trick
1726 * must be done before entering to the loop below.
1727 */
69310a67 1728 /* XXX: Why is this Opaque specific? Either our core code is deficient
1729 * and this should be fixed generally, or Opaque is inventing strawman
1730 * problems */
718e3744 1731 ospf_opaque_adjust_lsreq (nbr, lsas);
1732#endif /* HAVE_OPAQUE_LSA */
1733
1734#define DISCARD_LSA(L,N) {\
1735 if (IS_DEBUG_OSPF_EVENT) \
2a42e285 1736 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
718e3744 1737 ospf_lsa_discard (L); \
1738 continue; }
1739
1740 /* Process each LSA received in the one packet. */
1eb8ef25 1741 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
718e3744 1742 {
1743 struct ospf_lsa *ls_ret, *current;
1744 int ret = 1;
1745
718e3744 1746 if (IS_DEBUG_OSPF_NSSA)
1747 {
1748 char buf1[INET_ADDRSTRLEN];
1749 char buf2[INET_ADDRSTRLEN];
1750 char buf3[INET_ADDRSTRLEN];
1751
2a42e285 1752 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
718e3744 1753 lsa->data->type,
1754 inet_ntop (AF_INET, &ospfh->router_id,
1755 buf1, INET_ADDRSTRLEN),
1756 inet_ntop (AF_INET, &lsa->data->id,
1757 buf2, INET_ADDRSTRLEN),
1758 inet_ntop (AF_INET, &lsa->data->adv_router,
1759 buf3, INET_ADDRSTRLEN));
1760 }
718e3744 1761
1762 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1763
1764 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1765
1766 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1767
1768 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1769
1770 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1771
1772 /* Do take in Type-7's if we are an NSSA */
1773
1774 /* If we are also an ABR, later translate them to a Type-5 packet */
1775
1776 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1777 translate them to a separate Type-5 packet. */
1778
1779 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1780 /* Reject from STUB or NSSA */
1781 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1782 {
718e3744 1783 if (IS_DEBUG_OSPF_NSSA)
2a42e285 1784 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
2cd754de 1785 DISCARD_LSA (lsa, 1);
718e3744 1786 }
1787
718e3744 1788 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1789 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1790 {
718e3744 1791 if (IS_DEBUG_OSPF_NSSA)
2a42e285 1792 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
2cd754de 1793 DISCARD_LSA (lsa,2);
718e3744 1794 }
718e3744 1795
1796 /* Find the LSA in the current database. */
1797
1798 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1799
1800 /* If the LSA's LS age is equal to MaxAge, and there is currently
1801 no instance of the LSA in the router's link state database,
1802 and none of router's neighbors are in states Exchange or Loading,
1803 then take the following actions. */
1804
1805 if (IS_LSA_MAXAGE (lsa) && !current &&
68980084 1806 (ospf_nbr_count (oi, NSM_Exchange) +
1807 ospf_nbr_count (oi, NSM_Loading)) == 0)
718e3744 1808 {
1809 /* Response Link State Acknowledgment. */
1810 ospf_ls_ack_send (nbr, lsa);
1811
1812 /* Discard LSA. */
6d45276f 1813 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1814 dump_lsa_key(lsa));
718e3744 1815 DISCARD_LSA (lsa, 3);
1816 }
1817
1818#ifdef HAVE_OPAQUE_LSA
1819 if (IS_OPAQUE_LSA (lsa->data->type)
68980084 1820 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
718e3744 1821 {
1822 /*
1823 * Even if initial flushing seems to be completed, there might
1824 * be a case that self-originated LSA with MaxAge still remain
1825 * in the routing domain.
1826 * Just send an LSAck message to cease retransmission.
1827 */
1828 if (IS_LSA_MAXAGE (lsa))
1829 {
1830 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1831 ospf_ls_ack_send (nbr, lsa);
1832 ospf_lsa_discard (lsa);
1833
1834 if (current != NULL && ! IS_LSA_MAXAGE (current))
1835 ospf_opaque_lsa_refresh_schedule (current);
1836 continue;
1837 }
1838
1839 /*
1840 * If an instance of self-originated Opaque-LSA is not found
1841 * in the LSDB, there are some possible cases here.
1842 *
1843 * 1) This node lost opaque-capability after restart.
1844 * 2) Else, a part of opaque-type is no more supported.
1845 * 3) Else, a part of opaque-id is no more supported.
1846 *
1847 * Anyway, it is still this node's responsibility to flush it.
1848 * Otherwise, the LSA instance remains in the routing domain
1849 * until its age reaches to MaxAge.
1850 */
69310a67 1851 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
718e3744 1852 if (current == NULL)
1853 {
1854 if (IS_DEBUG_OSPF_EVENT)
69310a67 1855 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1856 "not found in the LSDB.", dump_lsa_key (lsa));
718e3744 1857
1858 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
69310a67 1859
1860 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1861 ospf_ls_ack_send (nbr, lsa);
1862
718e3744 1863 continue;
1864 }
1865 }
1866#endif /* HAVE_OPAQUE_LSA */
69310a67 1867
cb05eb28 1868 /* It might be happen that received LSA is self-originated network LSA, but
1869 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1870 * Link State ID is one of the router's own IP interface addresses but whose
1871 * Advertising Router is not equal to the router's own Router ID
1872 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1873 */
1874
1875 if(lsa->data->type == OSPF_NETWORK_LSA)
1876 {
1eb8ef25 1877 struct listnode *oinode, *oinnode;
1878 struct ospf_interface *out_if;
cb05eb28 1879 int Flag = 0;
1880
1eb8ef25 1881 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
cb05eb28 1882 {
cb05eb28 1883 if(out_if == NULL)
1884 break;
1885
1886 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1887 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1888 {
1889 if(out_if->network_lsa_self)
1890 {
1891 ospf_lsa_flush_area(lsa,out_if->area);
1892 if(IS_DEBUG_OSPF_EVENT)
2a42e285 1893 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
cb05eb28 1894 lsa, (int) lsa->data->type);
1895 ospf_lsa_discard (lsa);
1896 Flag = 1;
1897 }
1898 break;
1899 }
1900 }
1901 if(Flag)
1902 continue;
1903 }
718e3744 1904
1905 /* (5) Find the instance of this LSA that is currently contained
1906 in the router's link state database. If there is no
1907 database copy, or the received LSA is more recent than
1908 the database copy the following steps must be performed. */
1909
1910 if (current == NULL ||
1911 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1912 {
1913 /* Actual flooding procedure. */
68980084 1914 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
718e3744 1915 DISCARD_LSA (lsa, 4);
1916 continue;
1917 }
1918
1919 /* (6) Else, If there is an instance of the LSA on the sending
1920 neighbor's Link state request list, an error has occurred in
1921 the Database Exchange process. In this case, restart the
1922 Database Exchange process by generating the neighbor event
1923 BadLSReq for the sending neighbor and stop processing the
1924 Link State Update packet. */
1925
1926 if (ospf_ls_request_lookup (nbr, lsa))
1927 {
1928 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
3aa8d5f9 1929 zlog_warn("LSA[%s] instance exists on Link state request list",
1930 dump_lsa_key(lsa));
718e3744 1931
1932 /* Clean list of LSAs. */
1933 ospf_upd_list_clean (lsas);
1934 /* this lsa is not on lsas list already. */
1935 ospf_lsa_discard (lsa);
718e3744 1936 return;
1937 }
1938
1939 /* If the received LSA is the same instance as the database copy
1940 (i.e., neither one is more recent) the following two steps
1941 should be performed: */
1942
1943 if (ret == 0)
1944 {
1945 /* If the LSA is listed in the Link state retransmission list
1946 for the receiving adjacency, the router itself is expecting
1947 an acknowledgment for this LSA. The router should treat the
1948 received LSA as an acknowledgment by removing the LSA from
1949 the Link state retransmission list. This is termed an
1950 "implied acknowledgment". */
1951
1952 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1953
1954 if (ls_ret != NULL)
1955 {
1956 ospf_ls_retransmit_delete (nbr, ls_ret);
1957
1958 /* Delayed acknowledgment sent if advertisement received
1959 from Designated Router, otherwise do nothing. */
1960 if (oi->state == ISM_Backup)
1961 if (NBR_IS_DR (nbr))
1962 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1963
1964 DISCARD_LSA (lsa, 5);
1965 }
1966 else
1967 /* Acknowledge the receipt of the LSA by sending a
1968 Link State Acknowledgment packet back out the receiving
1969 interface. */
1970 {
1971 ospf_ls_ack_send (nbr, lsa);
1972 DISCARD_LSA (lsa, 6);
1973 }
1974 }
1975
1976 /* The database copy is more recent. If the database copy
1977 has LS age equal to MaxAge and LS sequence number equal to
1978 MaxSequenceNumber, simply discard the received LSA without
1979 acknowledging it. (In this case, the LSA's LS sequence number is
1980 wrapping, and the MaxSequenceNumber LSA must be completely
1981 flushed before any new LSA instance can be introduced). */
1982
1983 else if (ret > 0) /* Database copy is more recent */
1984 {
1985 if (IS_LSA_MAXAGE (current) &&
1986 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1987 {
1988 DISCARD_LSA (lsa, 7);
1989 }
1990 /* Otherwise, as long as the database copy has not been sent in a
1991 Link State Update within the last MinLSArrival seconds, send the
1992 database copy back to the sending neighbor, encapsulated within
1993 a Link State Update Packet. The Link State Update Packet should
1994 be sent directly to the neighbor. In so doing, do not put the
1995 database copy of the LSA on the neighbor's link state
1996 retransmission list, and do not acknowledge the received (less
1997 recent) LSA instance. */
1998 else
1999 {
2000 struct timeval now;
2001
2518efd1 2002 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
718e3744 2003
2004 if (tv_cmp (tv_sub (now, current->tv_orig),
2c9f8e36 2005 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
718e3744 2006 /* Trap NSSA type later.*/
2007 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2008 DISCARD_LSA (lsa, 8);
2009 }
2010 }
2011 }
2cd754de
PJ
2012#undef DISCARD_LSA
2013
718e3744 2014 assert (listcount (lsas) == 0);
2015 list_delete (lsas);
2016}
2017
2018/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
4dadc291 2019static void
718e3744 2020ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2021 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2022{
2023 struct ospf_neighbor *nbr;
69310a67 2024
718e3744 2025 /* increment statistics. */
2026 oi->ls_ack_in++;
2027
d3f0d621 2028 nbr = ospf_nbr_lookup (oi, iph, ospfh);
718e3744 2029 if (nbr == NULL)
2030 {
2031 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2032 inet_ntoa (ospfh->router_id));
2033 return;
2034 }
2035
57c5c652
PJ
2036 /* Add event to thread. */
2037 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2038
718e3744 2039 if (nbr->state < NSM_Exchange)
2040 {
3aa8d5f9 2041 zlog_warn ("Link State Acknowledgment: "
2042 "Neighbor[%s] state %s is less than Exchange",
2043 inet_ntoa (ospfh->router_id),
2044 LOOKUP(ospf_nsm_state_msg, nbr->state));
718e3744 2045 return;
2046 }
69310a67 2047
718e3744 2048 while (size >= OSPF_LSA_HEADER_SIZE)
2049 {
2050 struct ospf_lsa *lsa, *lsr;
2051
2052 lsa = ospf_lsa_new ();
2053 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2054
2055 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2056 size -= OSPF_LSA_HEADER_SIZE;
9985f83c 2057 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
718e3744 2058
2059 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2060 {
2061 lsa->data = NULL;
2062 ospf_lsa_discard (lsa);
2063 continue;
2064 }
2065
2066 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2067
2068 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2069 {
2070#ifdef HAVE_OPAQUE_LSA
718e3744 2071 if (IS_OPAQUE_LSA (lsr->data->type))
69310a67 2072 ospf_opaque_ls_ack_received (nbr, lsr);
718e3744 2073#endif /* HAVE_OPAQUE_LSA */
2074
2075 ospf_ls_retransmit_delete (nbr, lsr);
2076 }
2077
2078 lsa->data = NULL;
2079 ospf_lsa_discard (lsa);
2080 }
2081
718e3744 2082 return;
718e3744 2083}
2084\f
038163fa 2085static struct stream *
5c33349b 2086ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
718e3744 2087{
2088 int ret;
5c33349b 2089 struct ip *iph;
718e3744 2090 u_int16_t ip_len;
718e3744 2091 unsigned int ifindex = 0;
2092 struct iovec iov;
d0deca68 2093 /* Header and data both require alignment. */
e304982e 2094 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
2dd8bb4e 2095 struct msghdr msgh;
2096
68defd6d 2097 memset (&msgh, 0, sizeof (struct msghdr));
2dd8bb4e 2098 msgh.msg_iov = &iov;
2099 msgh.msg_iovlen = 1;
2100 msgh.msg_control = (caddr_t) buff;
2101 msgh.msg_controllen = sizeof (buff);
2dd8bb4e 2102
5c33349b 2103 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2104 if (ret < 0)
718e3744 2105 {
5c33349b 2106 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2107 return NULL;
2108 }
69310a67 2109 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
5c33349b 2110 {
2111 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2112 "(ip header size is %u)",
2113 ret, (u_int)sizeof(iph));
718e3744 2114 return NULL;
2115 }
18b12c38 2116
5c33349b 2117 /* Note that there should not be alignment problems with this assignment
2118 because this is at the beginning of the stream data buffer. */
2119 iph = (struct ip *) STREAM_DATA(ibuf);
2120 sockopt_iphdrincl_swab_systoh (iph);
18b12c38 2121
5c33349b 2122 ip_len = iph->ip_len;
6b333611 2123
de5ccb96 2124#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
718e3744 2125 /*
2126 * Kernel network code touches incoming IP header parameters,
2127 * before protocol specific processing.
2128 *
2129 * 1) Convert byteorder to host representation.
2130 * --> ip_len, ip_id, ip_off
2131 *
2132 * 2) Adjust ip_len to strip IP header size!
2133 * --> If user process receives entire IP packet via RAW
2134 * socket, it must consider adding IP header size to
2135 * the "ip_len" field of "ip" structure.
2136 *
2137 * For more details, see <netinet/ip_input.c>.
2138 */
5c33349b 2139 ip_len = ip_len + (iph->ip_hl << 2);
718e3744 2140#endif
2141
0150c9c9
DB
2142#if defined(__DragonFly__)
2143 /*
2144 * in DragonFly's raw socket, ip_len/ip_off are read
2145 * in network byte order.
2146 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2147 */
2148 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2149#endif
2150
863082d5 2151 ifindex = getsockopt_ifindex (AF_INET, &msgh);
718e3744 2152
2153 *ifp = if_lookup_by_index (ifindex);
2154
2155 if (ret != ip_len)
2156 {
5c33349b 2157 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2158 "but recvmsg returned %d", ip_len, ret);
718e3744 2159 return NULL;
2160 }
2161
2162 return ibuf;
2163}
2164
4dadc291 2165static struct ospf_interface *
d3f0d621 2166ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
718e3744 2167 struct ip *iph, struct ospf_header *ospfh)
2168{
2169 struct ospf_interface *rcv_oi;
718e3744 2170 struct ospf_vl_data *vl_data;
2171 struct ospf_area *vl_area;
52dc7ee6 2172 struct listnode *node;
718e3744 2173
2174 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2175 !OSPF_IS_AREA_BACKBONE (ospfh))
d3f0d621 2176 return NULL;
718e3744 2177
d3f0d621 2178 /* look for local OSPF interface matching the destination
2179 * to determine Area ID. We presume therefore the destination address
2180 * is unique, or at least (for "unnumbered" links), not used in other
2181 * areas
2182 */
2183 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2184 iph->ip_dst)) == NULL)
2185 return NULL;
718e3744 2186
1eb8ef25 2187 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
718e3744 2188 {
020709f9 2189 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
718e3744 2190 if (!vl_area)
2191 continue;
2192
2193 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2194 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2195 {
2196 if (IS_DEBUG_OSPF_EVENT)
2a42e285 2197 zlog_debug ("associating packet with %s",
718e3744 2198 IF_NAME (vl_data->vl_oi));
2199 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2200 {
2201 if (IS_DEBUG_OSPF_EVENT)
2a42e285 2202 zlog_debug ("This VL is not up yet, sorry");
718e3744 2203 return NULL;
2204 }
2205
2206 return vl_data->vl_oi;
2207 }
2208 }
2209
2210 if (IS_DEBUG_OSPF_EVENT)
2a42e285 2211 zlog_debug ("couldn't find any VL to associate the packet with");
718e3744 2212
d3f0d621 2213 return NULL;
718e3744 2214}
2215
f63f06da 2216static int
718e3744 2217ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2218{
2219 /* Check match the Area ID of the receiving interface. */
2220 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2221 return 1;
2222
2223 return 0;
2224}
2225
2226/* Unbound socket will accept any Raw IP packets if proto is matched.
2227 To prevent it, compare src IP address and i/f address with masking
2228 i/f network mask. */
4dadc291 2229static int
718e3744 2230ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2231{
2232 struct in_addr mask, me, him;
2233
2234 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2235 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2236 return 1;
2237
2238 masklen2ip (oi->address->prefixlen, &mask);
2239
2240 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2241 him.s_addr = ip_src.s_addr & mask.s_addr;
2242
2243 if (IPV4_ADDR_SAME (&me, &him))
2244 return 1;
2245
2246 return 0;
2247}
2248
4dadc291 2249static int
718e3744 2250ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2251 struct ospf_header *ospfh)
2252{
2253 int ret = 0;
2254 struct crypt_key *ck;
2255
2256 switch (ntohs (ospfh->auth_type))
2257 {
2258 case OSPF_AUTH_NULL:
2259 ret = 1;
2260 break;
2261 case OSPF_AUTH_SIMPLE:
2262 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2263 ret = 1;
2264 else
2265 ret = 0;
2266 break;
2267 case OSPF_AUTH_CRYPTOGRAPHIC:
1eb8ef25 2268 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
718e3744 2269 {
2270 ret = 0;
2271 break;
2272 }
2273
2274 /* This is very basic, the digest processing is elsewhere */
2275 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2276 ospfh->u.crypt.key_id == ck->key_id &&
2277 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2278 ret = 1;
2279 else
2280 ret = 0;
2281 break;
2282 default:
2283 ret = 0;
2284 break;
2285 }
2286
2287 return ret;
2288}
2289
4dadc291 2290static int
718e3744 2291ospf_check_sum (struct ospf_header *ospfh)
2292{
2293 u_int32_t ret;
2294 u_int16_t sum;
718e3744 2295
2296 /* clear auth_data for checksum. */
2297 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2298
2299 /* keep checksum and clear. */
2300 sum = ospfh->checksum;
2301 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2302
2303 /* calculate checksum. */
2304 ret = in_cksum (ospfh, ntohs (ospfh->length));
2305
2306 if (ret != sum)
2307 {
2308 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2309 ret, sum);
2310 return 0;
2311 }
2312
2313 return 1;
2314}
2315
2316/* OSPF Header verification. */
4dadc291 2317static int
718e3744 2318ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2319 struct ip *iph, struct ospf_header *ospfh)
2320{
2321 /* check version. */
2322 if (ospfh->version != OSPF_VERSION)
2323 {
2324 zlog_warn ("interface %s: ospf_read version number mismatch.",
2325 IF_NAME (oi));
2326 return -1;
2327 }
2328
71775043
DO
2329 /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
2330 if (ospfh->type < 1 || ospfh->type > 5)
2331 {
2332 zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
2333 return -1;
2334 }
2335
718e3744 2336 /* Check Area ID. */
2337 if (!ospf_check_area_id (oi, ospfh))
2338 {
2339 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2340 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2341 return -1;
2342 }
2343
2344 /* Check network mask, Silently discarded. */
2345 if (! ospf_check_network_mask (oi, iph->ip_src))
2346 {
2347 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2348 IF_NAME (oi), inet_ntoa (iph->ip_src));
2349 return -1;
2350 }
2351
2352 /* Check authentication. */
2353 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2354 {
c6371718 2355 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2356 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
718e3744 2357 return -1;
2358 }
2359
2360 if (! ospf_check_auth (oi, ibuf, ospfh))
2361 {
2362 zlog_warn ("interface %s: ospf_read authentication failed.",
2363 IF_NAME (oi));
2364 return -1;
2365 }
2366
2367 /* if check sum is invalid, packet is discarded. */
2368 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2369 {
2370 if (! ospf_check_sum (ospfh))
2371 {
2372 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2373 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2374 return -1;
2375 }
2376 }
2377 else
2378 {
2379 if (ospfh->checksum != 0)
2380 return -1;
2381 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2382 {
2383 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2384 IF_NAME (oi));
2385 return -1;
2386 }
2387 }
2388
2389 return 0;
2390}
2391
2392/* Starting point of packet process function. */
2393int
2394ospf_read (struct thread *thread)
2395{
2396 int ret;
2397 struct stream *ibuf;
68980084 2398 struct ospf *ospf;
718e3744 2399 struct ospf_interface *oi;
2400 struct ip *iph;
2401 struct ospf_header *ospfh;
2402 u_int16_t length;
2403 struct interface *ifp;
2404
2405 /* first of all get interface pointer. */
68980084 2406 ospf = THREAD_ARG (thread);
038163fa 2407
2408 /* prepare for next packet. */
2409 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
718e3744 2410
2411 /* read OSPF packet. */
5c33349b 2412 stream_reset(ospf->ibuf);
2413 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
718e3744 2414 return -1;
2415
5c33349b 2416 /* Note that there should not be alignment problems with this assignment
2417 because this is at the beginning of the stream data buffer. */
06f953f7 2418 iph = (struct ip *) STREAM_DATA (ibuf);
5c33349b 2419 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
06f953f7 2420
ac191232 2421 if (ifp == NULL)
b87f772a 2422 /* Handle cases where the platform does not support retrieving the ifindex,
2423 and also platforms (such as Solaris 8) that claim to support ifindex
2424 retrieval but do not. */
ac191232 2425 ifp = if_lookup_address (iph->ip_src);
ac191232 2426
d3f0d621 2427 if (ifp == NULL)
5c33349b 2428 return 0;
718e3744 2429
2430 /* IP Header dump. */
17b78d38 2431 if (IS_DEBUG_OSPF_PACKET(0, RECV))
6b333611 2432 ospf_ip_header_dump (iph);
7d95c611 2433
718e3744 2434 /* Self-originated packet should be discarded silently. */
68980084 2435 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
718e3744 2436 {
d324181c 2437 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2438 {
2a42e285 2439 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
d324181c 2440 inet_ntoa (iph->ip_src));
2441 }
718e3744 2442 return 0;
2443 }
2444
61ab0301
DO
2445 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2446 by ospf_recv_packet() to be correct). */
9985f83c 2447 stream_forward_getp (ibuf, iph->ip_hl * 4);
61ab0301
DO
2448
2449 /* Make sure the OSPF header is really there. */
2450 if (stream_get_endp (ibuf) - stream_get_getp (ibuf) < OSPF_HEADER_SIZE)
2451 {
2452 zlog_debug ("ospf_read: ignored OSPF packet with undersized (%u bytes) header",
2453 stream_get_endp (ibuf) - stream_get_getp (ibuf));
2454 return -1;
2455 }
2456
2457 /* Now it is safe to access all fields of OSPF packet header. */
718e3744 2458 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2459
2460 /* associate packet with ospf interface */
05cf46ba 2461 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
d3f0d621 2462
3aad46bd
YS
2463 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2464 after the passive/backbone/other checks below are passed. These checks
2465 in turn access the fields of unverified "ospfh" structure for their own
2466 purposes and must remain very accurate in doing this. */
71775043 2467
491eddc2
JT
2468 /* If incoming interface is passive one, ignore it. */
2469 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2470 {
2471 char buf[3][INET_ADDRSTRLEN];
2472
2473 if (IS_DEBUG_OSPF_EVENT)
2474 zlog_debug ("ignoring packet from router %s sent to %s, "
2475 "received on a passive interface, %s",
2476 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2477 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2478 inet_ntop(AF_INET, &oi->address->u.prefix4,
2479 buf[2], sizeof(buf[2])));
2480
2481 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2482 {
2483 /* Try to fix multicast membership.
2484 * Some OS:es may have problems in this area,
2485 * make sure it is removed.
2486 */
2487 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2488 ospf_if_set_multicast(oi);
2489 }
2490 return 0;
2491 }
2492
2493
d3f0d621 2494 /* if no local ospf_interface,
2495 * or header area is backbone but ospf_interface is not
2496 * check for VLINK interface
2497 */
2498 if ( (oi == NULL) ||
2499 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2500 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2501 )
718e3744 2502 {
d3f0d621 2503 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
d324181c 2504 {
88871b1d
PJ
2505 if (IS_DEBUG_OSPF_EVENT)
2506 zlog_debug ("Packet from [%s] received on link %s"
2507 " but no ospf_interface",
2508 inet_ntoa (iph->ip_src), ifp->name);
d3f0d621 2509 return 0;
d324181c 2510 }
d3f0d621 2511 }
05cf46ba 2512
d3f0d621 2513 /* else it must be a local ospf interface, check it was received on
2514 * correct link
2515 */
2516 else if (oi->ifp != ifp)
2517 {
11637435
PJ
2518 if (IS_DEBUG_OSPF_EVENT)
2519 zlog_warn ("Packet from [%s] received on wrong link %s",
2520 inet_ntoa (iph->ip_src), ifp->name);
718e3744 2521 return 0;
2522 }
847947f2 2523 else if (oi->state == ISM_Down)
c3eab871 2524 {
ba6454ec 2525 char buf[2][INET_ADDRSTRLEN];
2526 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
847947f2 2527 "down [%s]; interface flags are %s",
ba6454ec 2528 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2529 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2530 ifp->name, if_flag_dump(ifp->flags));
ba6454ec 2531 /* Fix multicast memberships? */
2532 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
429ac78c 2533 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ba6454ec 2534 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
429ac78c 2535 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ba6454ec 2536 if (oi->multicast_memberships)
2537 ospf_if_set_multicast(oi);
c3eab871 2538 return 0;
2539 }
718e3744 2540
2541 /*
2542 * If the received packet is destined for AllDRouters, the packet
2543 * should be accepted only if the received ospf interface state is
2544 * either DR or Backup -- endo.
2545 */
2546 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2547 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2548 {
ba6454ec 2549 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
718e3744 2550 inet_ntoa (iph->ip_src), IF_NAME (oi),
2551 LOOKUP (ospf_ism_state_msg, oi->state));
ba6454ec 2552 /* Try to fix multicast membership. */
2553 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2554 ospf_if_set_multicast(oi);
718e3744 2555 return 0;
2556 }
2557
3aad46bd
YS
2558 /* Verify more OSPF header fields. */
2559 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2560 if (ret < 0)
2561 {
2562 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2563 zlog_debug ("ospf_read[%s]: Header check failed, "
2564 "dropping.",
2565 inet_ntoa (iph->ip_src));
2566 return ret;
2567 }
2568
718e3744 2569 /* Show debug receiving packet. */
1aa7b399 2570 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2571 {
718e3744 2572 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
1aa7b399 2573 {
2a42e285 2574 zlog_debug ("-----------------------------------------------------");
1aa7b399 2575 ospf_packet_dump (ibuf);
2576 }
718e3744 2577
2a42e285 2578 zlog_debug ("%s received from [%s] via [%s]",
1aa7b399 2579 ospf_packet_type_str[ospfh->type],
2580 inet_ntoa (ospfh->router_id), IF_NAME (oi));
2a42e285 2581 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2582 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
718e3744 2583
2584 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2a42e285 2585 zlog_debug ("-----------------------------------------------------");
1aa7b399 2586 }
718e3744 2587
9985f83c 2588 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
718e3744 2589
2590 /* Adjust size to message length. */
2591 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2592
2593 /* Read rest of the packet and call each sort of packet routine. */
2594 switch (ospfh->type)
2595 {
2596 case OSPF_MSG_HELLO:
2597 ospf_hello (iph, ospfh, ibuf, oi, length);
2598 break;
2599 case OSPF_MSG_DB_DESC:
2600 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2601 break;
2602 case OSPF_MSG_LS_REQ:
2603 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2604 break;
2605 case OSPF_MSG_LS_UPD:
2606 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2607 break;
2608 case OSPF_MSG_LS_ACK:
2609 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2610 break;
2611 default:
2612 zlog (NULL, LOG_WARNING,
2613 "interface %s: OSPF packet header type %d is illegal",
2614 IF_NAME (oi), ospfh->type);
2615 break;
2616 }
2617
718e3744 2618 return 0;
2619}
2620
2621/* Make OSPF header. */
4dadc291 2622static void
718e3744 2623ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2624{
2625 struct ospf_header *ospfh;
2626
2627 ospfh = (struct ospf_header *) STREAM_DATA (s);
2628
2629 ospfh->version = (u_char) OSPF_VERSION;
2630 ospfh->type = (u_char) type;
2631
68980084 2632 ospfh->router_id = oi->ospf->router_id;
718e3744 2633
2634 ospfh->checksum = 0;
2635 ospfh->area_id = oi->area->area_id;
2636 ospfh->auth_type = htons (ospf_auth_type (oi));
2637
2638 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2639
9985f83c 2640 stream_forward_endp (s, OSPF_HEADER_SIZE);
718e3744 2641}
2642
2643/* Make Authentication Data. */
4dadc291 2644static int
718e3744 2645ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2646{
2647 struct crypt_key *ck;
2648
2649 switch (ospf_auth_type (oi))
2650 {
2651 case OSPF_AUTH_NULL:
2652 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2653 break;
2654 case OSPF_AUTH_SIMPLE:
2655 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2656 OSPF_AUTH_SIMPLE_SIZE);
2657 break;
2658 case OSPF_AUTH_CRYPTOGRAPHIC:
2659 /* If key is not set, then set 0. */
2660 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2661 {
2662 ospfh->u.crypt.zero = 0;
2663 ospfh->u.crypt.key_id = 0;
2664 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2665 }
2666 else
2667 {
1eb8ef25 2668 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
718e3744 2669 ospfh->u.crypt.zero = 0;
2670 ospfh->u.crypt.key_id = ck->key_id;
2671 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2672 }
2673 /* note: the seq is done in ospf_make_md5_digest() */
2674 break;
2675 default:
2676 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2677 break;
2678 }
2679
2680 return 0;
2681}
2682
2683/* Fill rest of OSPF header. */
4dadc291 2684static void
718e3744 2685ospf_fill_header (struct ospf_interface *oi,
2686 struct stream *s, u_int16_t length)
2687{
2688 struct ospf_header *ospfh;
2689
2690 ospfh = (struct ospf_header *) STREAM_DATA (s);
2691
2692 /* Fill length. */
2693 ospfh->length = htons (length);
2694
2695 /* Calculate checksum. */
2696 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2697 ospfh->checksum = in_cksum (ospfh, length);
2698 else
2699 ospfh->checksum = 0;
2700
2701 /* Add Authentication Data. */
2702 ospf_make_auth (oi, ospfh);
2703}
2704
4dadc291 2705static int
718e3744 2706ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2707{
2708 struct ospf_neighbor *nbr;
2709 struct route_node *rn;
2710 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2711 struct in_addr mask;
2712 unsigned long p;
2713 int flag = 0;
2714
2715 /* Set netmask of interface. */
2716 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2717 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2718 masklen2ip (oi->address->prefixlen, &mask);
2719 else
2720 memset ((char *) &mask, 0, sizeof (struct in_addr));
2721 stream_put_ipv4 (s, mask.s_addr);
2722
2723 /* Set Hello Interval. */
f9ad937f 2724 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2725 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2726 else
2727 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
718e3744 2728
2729 if (IS_DEBUG_OSPF_EVENT)
2a42e285 2730 zlog_debug ("make_hello: options: %x, int: %s",
718e3744 2731 OPTIONS(oi), IF_NAME (oi));
2732
2733 /* Set Options. */
2734 stream_putc (s, OPTIONS (oi));
2735
2736 /* Set Router Priority. */
2737 stream_putc (s, PRIORITY (oi));
2738
2739 /* Set Router Dead Interval. */
2740 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2741
2742 /* Set Designated Router. */
2743 stream_put_ipv4 (s, DR (oi).s_addr);
2744
9985f83c 2745 p = stream_get_endp (s);
718e3744 2746
2747 /* Set Backup Designated Router. */
2748 stream_put_ipv4 (s, BDR (oi).s_addr);
2749
2750 /* Add neighbor seen. */
2751 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
68980084 2752 if ((nbr = rn->info))
2753 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2754 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2755 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2756 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
718e3744 2757 {
2758 /* Check neighbor is sane? */
68980084 2759 if (nbr->d_router.s_addr != 0
2760 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2761 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2762 flag = 1;
718e3744 2763
2764 stream_put_ipv4 (s, nbr->router_id.s_addr);
2765 length += 4;
2766 }
2767
2768 /* Let neighbor generate BackupSeen. */
2769 if (flag == 1)
3a9eb091 2770 stream_putl_at (s, p, 0); /* ipv4 address, normally */
718e3744 2771
2772 return length;
2773}
2774
4dadc291 2775static int
718e3744 2776ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2777 struct stream *s)
2778{
2779 struct ospf_lsa *lsa;
2780 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2781 u_char options;
2782 unsigned long pp;
2783 int i;
2784 struct ospf_lsdb *lsdb;
2785
2786 /* Set Interface MTU. */
2787 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2788 stream_putw (s, 0);
2789 else
2790 stream_putw (s, oi->ifp->mtu);
2791
2792 /* Set Options. */
2793 options = OPTIONS (oi);
2794#ifdef HAVE_OPAQUE_LSA
68980084 2795 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
718e3744 2796 {
2797 if (IS_SET_DD_I (nbr->dd_flags)
2798 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2799 /*
2800 * Set O-bit in the outgoing DD packet for capablity negotiation,
2801 * if one of following case is applicable.
2802 *
2803 * 1) WaitTimer expiration event triggered the neighbor state to
2804 * change to Exstart, but no (valid) DD packet has received
2805 * from the neighbor yet.
2806 *
2807 * 2) At least one DD packet with O-bit on has received from the
2808 * neighbor.
2809 */
2810 SET_FLAG (options, OSPF_OPTION_O);
2811 }
2812#endif /* HAVE_OPAQUE_LSA */
2813 stream_putc (s, options);
2814
8dd24ee6 2815 /* DD flags */
9985f83c 2816 pp = stream_get_endp (s);
718e3744 2817 stream_putc (s, nbr->dd_flags);
2818
2819 /* Set DD Sequence Number. */
2820 stream_putl (s, nbr->dd_seqnum);
2821
b5aeb441 2822 /* shortcut unneeded walk of (empty) summary LSDBs */
718e3744 2823 if (ospf_db_summary_isempty (nbr))
b5aeb441 2824 goto empty;
718e3744 2825
2826 /* Describe LSA Header from Database Summary List. */
2827 lsdb = &nbr->db_sum;
2828
2829 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2830 {
2831 struct route_table *table = lsdb->type[i].db;
2832 struct route_node *rn;
2833
2834 for (rn = route_top (table); rn; rn = route_next (rn))
2835 if ((lsa = rn->info) != NULL)
2836 {
2837#ifdef HAVE_OPAQUE_LSA
2838 if (IS_OPAQUE_LSA (lsa->data->type)
2839 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2840 {
2841 /* Suppress advertising opaque-informations. */
2842 /* Remove LSA from DB summary list. */
2843 ospf_lsdb_delete (lsdb, lsa);
2844 continue;
2845 }
2846#endif /* HAVE_OPAQUE_LSA */
2847
2848 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2849 {
2850 struct lsa_header *lsah;
2851 u_int16_t ls_age;
2852
2853 /* DD packet overflows interface MTU. */
86f1fd96 2854 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
718e3744 2855 break;
2856
2857 /* Keep pointer to LS age. */
2858 lsah = (struct lsa_header *) (STREAM_DATA (s) +
9985f83c 2859 stream_get_endp (s));
718e3744 2860
2861 /* Proceed stream pointer. */
2862 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2863 length += OSPF_LSA_HEADER_SIZE;
2864
2865 /* Set LS age. */
2866 ls_age = LS_AGE (lsa);
2867 lsah->ls_age = htons (ls_age);
2868
2869 }
2870
2871 /* Remove LSA from DB summary list. */
2872 ospf_lsdb_delete (lsdb, lsa);
2873 }
2874 }
2875
8dd24ee6
PJ
2876 /* Update 'More' bit */
2877 if (ospf_db_summary_isempty (nbr))
2878 {
b5aeb441
PJ
2879empty:
2880 if (nbr->state >= NSM_Exchange)
2881 {
2882 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2883 /* Rewrite DD flags */
2884 stream_putc_at (s, pp, nbr->dd_flags);
2885 }
2886 else
2887 {
2888 assert (IS_SET_DD_M(nbr->dd_flags));
2889 }
8dd24ee6 2890 }
718e3744 2891 return length;
2892}
2893
4dadc291 2894static int
718e3744 2895ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2896 unsigned long delta, struct ospf_neighbor *nbr,
2897 struct ospf_lsa *lsa)
2898{
2899 struct ospf_interface *oi;
2900
2901 oi = nbr->oi;
2902
2903 /* LS Request packet overflows interface MTU. */
86f1fd96 2904 if (*length + delta > ospf_packet_max(oi))
718e3744 2905 return 0;
2906
2907 stream_putl (s, lsa->data->type);
2908 stream_put_ipv4 (s, lsa->data->id.s_addr);
2909 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2910
1fe6ed38 2911 ospf_lsa_unlock (&nbr->ls_req_last);
718e3744 2912 nbr->ls_req_last = ospf_lsa_lock (lsa);
2913
2914 *length += 12;
2915 return 1;
2916}
2917
4dadc291 2918static int
718e3744 2919ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2920{
2921 struct ospf_lsa *lsa;
2922 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
9985f83c 2923 unsigned long delta = stream_get_endp(s)+12;
718e3744 2924 struct route_table *table;
2925 struct route_node *rn;
2926 int i;
2927 struct ospf_lsdb *lsdb;
2928
2929 lsdb = &nbr->ls_req;
2930
2931 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2932 {
2933 table = lsdb->type[i].db;
2934 for (rn = route_top (table); rn; rn = route_next (rn))
2935 if ((lsa = (rn->info)) != NULL)
2936 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2937 {
2938 route_unlock_node (rn);
2939 break;
2940 }
2941 }
2942 return length;
2943}
2944
4dadc291 2945static int
718e3744 2946ls_age_increment (struct ospf_lsa *lsa, int delay)
2947{
2948 int age;
2949
2950 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2951
2952 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2953}
2954
4dadc291 2955static int
52dc7ee6 2956ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
718e3744 2957{
2958 struct ospf_lsa *lsa;
52dc7ee6 2959 struct listnode *node;
c9035ccd 2960 u_int16_t length = 0;
86f1fd96 2961 unsigned int size_noauth;
9985f83c 2962 unsigned long delta = stream_get_endp (s);
718e3744 2963 unsigned long pp;
2964 int count = 0;
2965
2966 if (IS_DEBUG_OSPF_EVENT)
2a42e285 2967 zlog_debug ("ospf_make_ls_upd: Start");
59ea14c6 2968
9985f83c 2969 pp = stream_get_endp (s);
2970 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
c9035ccd 2971 length += OSPF_LS_UPD_MIN_SIZE;
718e3744 2972
86f1fd96 2973 /* Calculate amount of packet usable for data. */
2974 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2975
718e3744 2976 while ((node = listhead (update)) != NULL)
2977 {
2978 struct lsa_header *lsah;
2979 u_int16_t ls_age;
2980
2981 if (IS_DEBUG_OSPF_EVENT)
2a42e285 2982 zlog_debug ("ospf_make_ls_upd: List Iteration");
718e3744 2983
1eb8ef25 2984 lsa = listgetdata (node);
2985
718e3744 2986 assert (lsa->data);
2987
68b7339a 2988 /* Will it fit? */
86f1fd96 2989 if (length + delta + ntohs (lsa->data->length) > size_noauth)
59ea14c6 2990 break;
2991
718e3744 2992 /* Keep pointer to LS age. */
9985f83c 2993 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
718e3744 2994
2995 /* Put LSA to Link State Request. */
2996 stream_put (s, lsa->data, ntohs (lsa->data->length));
2997
2998 /* Set LS age. */
2999 /* each hop must increment an lsa_age by transmit_delay
3000 of OSPF interface */
3001 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3002 lsah->ls_age = htons (ls_age);
3003
3004 length += ntohs (lsa->data->length);
3005 count++;
3006
3007 list_delete_node (update, node);
1fe6ed38 3008 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
718e3744 3009 }
3010
3011 /* Now set #LSAs. */
3a9eb091 3012 stream_putl_at (s, pp, count);
718e3744 3013
3014 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3015 zlog_debug ("ospf_make_ls_upd: Stop");
718e3744 3016 return length;
3017}
3018
4dadc291 3019static int
52dc7ee6 3020ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
718e3744 3021{
1fe6ed38 3022 struct listnode *node, *nnode;
718e3744 3023 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
9985f83c 3024 unsigned long delta = stream_get_endp(s) + 24;
718e3744 3025 struct ospf_lsa *lsa;
3026
1fe6ed38 3027 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
718e3744 3028 {
718e3744 3029 assert (lsa);
3030
86f1fd96 3031 if (length + delta > ospf_packet_max (oi))
718e3744 3032 break;
3033
3034 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3035 length += OSPF_LSA_HEADER_SIZE;
3036
718e3744 3037 listnode_delete (ack, lsa);
1fe6ed38 3038 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
718e3744 3039 }
3040
718e3744 3041 return length;
3042}
3043
aa276fd7
PJ
3044static void
3045ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
718e3744 3046{
3047 struct ospf_packet *op;
3048 u_int16_t length = OSPF_HEADER_SIZE;
3049
3050 op = ospf_packet_new (oi->ifp->mtu);
3051
3052 /* Prepare OSPF common header. */
3053 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3054
3055 /* Prepare OSPF Hello body. */
3056 length += ospf_make_hello (oi, op->s);
3057
3058 /* Fill OSPF header. */
3059 ospf_fill_header (oi, op->s, length);
3060
3061 /* Set packet length. */
3062 op->length = length;
3063
aa276fd7 3064 op->dst.s_addr = addr;
718e3744 3065
aa276fd7
PJ
3066 /* Add packet to the top of the interface output queue, so that they
3067 * can't get delayed by things like long queues of LS Update packets
3068 */
3069 ospf_packet_add_top (oi, op);
718e3744 3070
3071 /* Hook thread to write packet. */
020709f9 3072 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3073}
3074
4dadc291 3075static void
718e3744 3076ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3077{
3078 struct ospf_interface *oi;
3079
3080 oi = nbr_nbma->oi;
3081 assert(oi);
3082
3083 /* If this is passive interface, do not send OSPF Hello. */
7ffa8fa2 3084 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
718e3744 3085 return;
3086
3087 if (oi->type != OSPF_IFTYPE_NBMA)
3088 return;
3089
3090 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3091 return;
3092
3093 if (PRIORITY(oi) == 0)
3094 return;
3095
3096 if (nbr_nbma->priority == 0
3097 && oi->state != ISM_DR && oi->state != ISM_Backup)
3098 return;
3099
aa276fd7 3100 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
718e3744 3101}
3102
3103int
3104ospf_poll_timer (struct thread *thread)
3105{
3106 struct ospf_nbr_nbma *nbr_nbma;
3107
3108 nbr_nbma = THREAD_ARG (thread);
3109 nbr_nbma->t_poll = NULL;
3110
3111 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2a42e285 3112 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
718e3744 3113 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3114
3115 ospf_poll_send (nbr_nbma);
3116
3117 if (nbr_nbma->v_poll > 0)
3118 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3119 nbr_nbma->v_poll);
3120
3121 return 0;
3122}
3123
3124
3125int
3126ospf_hello_reply_timer (struct thread *thread)
3127{
3128 struct ospf_neighbor *nbr;
3129
3130 nbr = THREAD_ARG (thread);
3131 nbr->t_hello_reply = NULL;
3132
3133 assert (nbr->oi);
3134
3135 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2a42e285 3136 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
718e3744 3137 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3138
aa276fd7 3139 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
718e3744 3140
3141 return 0;
3142}
3143
3144/* Send OSPF Hello. */
3145void
3146ospf_hello_send (struct ospf_interface *oi)
3147{
718e3744 3148 /* If this is passive interface, do not send OSPF Hello. */
7ffa8fa2 3149 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
718e3744 3150 return;
3151
718e3744 3152 if (oi->type == OSPF_IFTYPE_NBMA)
3153 {
3154 struct ospf_neighbor *nbr;
3155 struct route_node *rn;
3156
3157 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3158 if ((nbr = rn->info))
3159 if (nbr != oi->nbr_self)
3160 if (nbr->state != NSM_Down)
3161 {
3162 /* RFC 2328 Section 9.5.1
3163 If the router is not eligible to become Designated Router,
3164 it must periodically send Hello Packets to both the
3165 Designated Router and the Backup Designated Router (if they
3166 exist). */
3167 if (PRIORITY(oi) == 0 &&
3168 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3169 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3170 continue;
3171
3172 /* If the router is eligible to become Designated Router, it
3173 must periodically send Hello Packets to all neighbors that
3174 are also eligible. In addition, if the router is itself the
3175 Designated Router or Backup Designated Router, it must also
3176 send periodic Hello Packets to all other neighbors. */
3177
3178 if (nbr->priority == 0 && oi->state == ISM_DROther)
3179 continue;
3180 /* if oi->state == Waiting, send hello to all neighbors */
aa276fd7 3181 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
718e3744 3182 }
718e3744 3183 }
3184 else
3185 {
3186 /* Decide destination address. */
3187 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
aa276fd7
PJ
3188 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3189 else
3190 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
718e3744 3191 }
3192}
3193
3194/* Send OSPF Database Description. */
3195void
3196ospf_db_desc_send (struct ospf_neighbor *nbr)
3197{
3198 struct ospf_interface *oi;
3199 struct ospf_packet *op;
3200 u_int16_t length = OSPF_HEADER_SIZE;
3201
3202 oi = nbr->oi;
3203 op = ospf_packet_new (oi->ifp->mtu);
3204
3205 /* Prepare OSPF common header. */
3206 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3207
3208 /* Prepare OSPF Database Description body. */
3209 length += ospf_make_db_desc (oi, nbr, op->s);
3210
3211 /* Fill OSPF header. */
3212 ospf_fill_header (oi, op->s, length);
3213
3214 /* Set packet length. */
3215 op->length = length;
3216
3217 /* Decide destination address. */
53d0dece
JT
3218 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3219 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3220 else
3221 op->dst = nbr->address.u.prefix4;
718e3744 3222
3223 /* Add packet to the interface output queue. */
3224 ospf_packet_add (oi, op);
3225
3226 /* Hook thread to write packet. */
020709f9 3227 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3228
3229 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3230 if (nbr->last_send)
3231 ospf_packet_free (nbr->last_send);
3232 nbr->last_send = ospf_packet_dup (op);
2518efd1 3233 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
718e3744 3234}
3235
3236/* Re-send Database Description. */
3237void
3238ospf_db_desc_resend (struct ospf_neighbor *nbr)
3239{
3240 struct ospf_interface *oi;
3241
3242 oi = nbr->oi;
3243
3244 /* Add packet to the interface output queue. */
3245 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3246
3247 /* Hook thread to write packet. */
020709f9 3248 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3249}
3250
3251/* Send Link State Request. */
3252void
3253ospf_ls_req_send (struct ospf_neighbor *nbr)
3254{
3255 struct ospf_interface *oi;
3256 struct ospf_packet *op;
3257 u_int16_t length = OSPF_HEADER_SIZE;
3258
3259 oi = nbr->oi;
3260 op = ospf_packet_new (oi->ifp->mtu);
3261
3262 /* Prepare OSPF common header. */
3263 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3264
3265 /* Prepare OSPF Link State Request body. */
3266 length += ospf_make_ls_req (nbr, op->s);
3267 if (length == OSPF_HEADER_SIZE)
3268 {
3269 ospf_packet_free (op);
3270 return;
3271 }
3272
3273 /* Fill OSPF header. */
3274 ospf_fill_header (oi, op->s, length);
3275
3276 /* Set packet length. */
3277 op->length = length;
3278
3279 /* Decide destination address. */
53d0dece
JT
3280 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3281 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3282 else
3283 op->dst = nbr->address.u.prefix4;
718e3744 3284
3285 /* Add packet to the interface output queue. */
3286 ospf_packet_add (oi, op);
3287
3288 /* Hook thread to write packet. */
020709f9 3289 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3290
3291 /* Add Link State Request Retransmission Timer. */
3292 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3293}
3294
3295/* Send Link State Update with an LSA. */
3296void
3297ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3298 int flag)
3299{
52dc7ee6 3300 struct list *update;
718e3744 3301
3302 update = list_new ();
3303
3304 listnode_add (update, lsa);
3305 ospf_ls_upd_send (nbr, update, flag);
3306
3307 list_delete (update);
3308}
3309
68b7339a 3310/* Determine size for packet. Must be at least big enough to accomodate next
3311 * LSA on list, which may be bigger than MTU size.
3312 *
3313 * Return pointer to new ospf_packet
3314 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3315 * on packet sizes (in which case offending LSA is deleted from update list)
3316 */
3317static struct ospf_packet *
3318ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3319{
3320 struct ospf_lsa *lsa;
3321 struct listnode *ln;
3322 size_t size;
3323 static char warned = 0;
3324
1eb8ef25 3325 lsa = listgetdata((ln = listhead (update)));
68b7339a 3326 assert (lsa->data);
3327
3328 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3329 > ospf_packet_max (oi))
3330 {
3331 if (!warned)
3332 {
3333 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3334 "will need to fragment. Not optimal. Try divide up"
3335 " your network with areas. Use 'debug ospf packet send'"
3336 " to see details, or look at 'show ip ospf database ..'");
3337 warned = 1;
3338 }
3339
3340 if (IS_DEBUG_OSPF_PACKET (0, SEND))
2a42e285 3341 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
68b7339a 3342 " %d bytes originated by %s, will be fragmented!",
3343 inet_ntoa (lsa->data->id),
3344 ntohs (lsa->data->length),
3345 inet_ntoa (lsa->data->adv_router));
3346
3347 /*
3348 * Allocate just enough to fit this LSA only, to avoid including other
3349 * LSAs in fragmented LSA Updates.
3350 */
3351 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3352 + OSPF_LS_UPD_MIN_SIZE;
3353 }
3354 else
3355 size = oi->ifp->mtu;
3356
3357 if (size > OSPF_MAX_PACKET_SIZE)
3358 {
3359 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
64511f39 3360 " %d bytes, packet size %ld, dropping it completely."
68b7339a 3361 " OSPF routing is broken!",
37ccfa3d 3362 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
62d8e96a 3363 (long int) size);
68b7339a 3364 list_delete_node (update, ln);
3365 return NULL;
3366 }
3367
c9035ccd
DT
3368 /* IP header is built up separately by ospf_write(). This means, that we must
3369 * reduce the "affordable" size just calculated by length of an IP header.
3370 * This makes sure, that even if we manage to fill the payload with LSA data
3371 * completely, the final packet (our data plus IP header) still fits into
3372 * outgoing interface MTU. This correction isn't really meaningful for an
3373 * oversized LSA, but for consistency the correction is done for both cases.
3374 *
3375 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3376 */
3377 return ospf_packet_new (size - sizeof (struct ip));
68b7339a 3378}
3379
718e3744 3380static void
52dc7ee6 3381ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
718e3744 3382 struct in_addr addr)
3383{
3384 struct ospf_packet *op;
3385 u_int16_t length = OSPF_HEADER_SIZE;
3386
3387 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3388 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
68b7339a 3389
3390 op = ospf_ls_upd_packet_new (update, oi);
718e3744 3391
3392 /* Prepare OSPF common header. */
3393 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3394
59ea14c6 3395 /* Prepare OSPF Link State Update body.
3396 * Includes Type-7 translation.
3397 */
718e3744 3398 length += ospf_make_ls_upd (oi, update, op->s);
3399
3400 /* Fill OSPF header. */
3401 ospf_fill_header (oi, op->s, length);
3402
3403 /* Set packet length. */
3404 op->length = length;
3405
3406 /* Decide destination address. */
53d0dece
JT
3407 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3408 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3409 else
3410 op->dst.s_addr = addr.s_addr;
718e3744 3411
3412 /* Add packet to the interface output queue. */
3413 ospf_packet_add (oi, op);
3414
3415 /* Hook thread to write packet. */
020709f9 3416 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3417}
3418
3419static int
3420ospf_ls_upd_send_queue_event (struct thread *thread)
3421{
3422 struct ospf_interface *oi = THREAD_ARG(thread);
3423 struct route_node *rn;
736d3441 3424 struct route_node *rnext;
59ea14c6 3425 struct list *update;
68b7339a 3426 char again = 0;
718e3744 3427
3428 oi->t_ls_upd_event = NULL;
3429
3430 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3431 zlog_debug ("ospf_ls_upd_send_queue start");
718e3744 3432
736d3441 3433 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
718e3744 3434 {
736d3441 3435 rnext = route_next (rn);
3436
718e3744 3437 if (rn->info == NULL)
736d3441 3438 continue;
68b7339a 3439
3440 update = (struct list *)rn->info;
718e3744 3441
48fe13bf 3442 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
718e3744 3443
68b7339a 3444 /* list might not be empty. */
59ea14c6 3445 if (listcount(update) == 0)
3446 {
3447 list_delete (rn->info);
3448 rn->info = NULL;
3449 route_unlock_node (rn);
3450 }
3451 else
68b7339a 3452 again = 1;
59ea14c6 3453 }
3454
3455 if (again != 0)
3456 {
3457 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3458 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
59ea14c6 3459 " %d nodes to try again, raising new event", again);
3460 oi->t_ls_upd_event =
3461 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
718e3744 3462 }
3463
3464 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3465 zlog_debug ("ospf_ls_upd_send_queue stop");
59ea14c6 3466
718e3744 3467 return 0;
3468}
3469
3470void
52dc7ee6 3471ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
718e3744 3472{
3473 struct ospf_interface *oi;
1eb8ef25 3474 struct ospf_lsa *lsa;
718e3744 3475 struct prefix_ipv4 p;
3476 struct route_node *rn;
1eb8ef25 3477 struct listnode *node;
718e3744 3478
3479 oi = nbr->oi;
3480
3481 p.family = AF_INET;
3482 p.prefixlen = IPV4_MAX_BITLEN;
3483
3484 /* Decide destination address. */
3485 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3486 p.prefix = oi->vl_data->peer_addr;
53d0dece
JT
3487 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3488 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
718e3744 3489 else if (flag == OSPF_SEND_PACKET_DIRECT)
3490 p.prefix = nbr->address.u.prefix4;
3491 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3492 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
7afa08da 3493 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3494 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
718e3744 3495 else
3496 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3497
3498 if (oi->type == OSPF_IFTYPE_NBMA)
3499 {
3500 if (flag == OSPF_SEND_PACKET_INDIRECT)
3501 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3502 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3503 zlog_warn ("* LS-Update is sent to myself.");
3504 }
3505
3506 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3507
3508 if (rn->info == NULL)
3509 rn->info = list_new ();
3510
1eb8ef25 3511 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
1fe6ed38 3512 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
718e3744 3513
3514 if (oi->t_ls_upd_event == NULL)
3515 oi->t_ls_upd_event =
3516 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3517}
3518
3519static void
52dc7ee6 3520ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3521 struct in_addr dst)
718e3744 3522{
3523 struct ospf_packet *op;
3524 u_int16_t length = OSPF_HEADER_SIZE;
3525
3526 op = ospf_packet_new (oi->ifp->mtu);
3527
3528 /* Prepare OSPF common header. */
3529 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3530
3531 /* Prepare OSPF Link State Acknowledgment body. */
3532 length += ospf_make_ls_ack (oi, ack, op->s);
3533
3534 /* Fill OSPF header. */
3535 ospf_fill_header (oi, op->s, length);
3536
3537 /* Set packet length. */
3538 op->length = length;
3539
3540 /* Set destination IP address. */
3541 op->dst = dst;
3542
3543 /* Add packet to the interface output queue. */
3544 ospf_packet_add (oi, op);
3545
3546 /* Hook thread to write packet. */
020709f9 3547 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3548}
3549
3550static int
3551ospf_ls_ack_send_event (struct thread *thread)
3552{
3553 struct ospf_interface *oi = THREAD_ARG (thread);
3554
3555 oi->t_ls_ack_direct = NULL;
3556
3557 while (listcount (oi->ls_ack_direct.ls_ack))
3558 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3559 oi->ls_ack_direct.dst);
3560
3561 return 0;
3562}
3563
3564void
3565ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3566{
3567 struct ospf_interface *oi = nbr->oi;
3568
3569 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3570 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3571
3572 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3573
3574 if (oi->t_ls_ack_direct == NULL)
3575 oi->t_ls_ack_direct =
3576 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3577}
3578
3579/* Send Link State Acknowledgment delayed. */
3580void
3581ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3582{
3583 struct in_addr dst;
3584
3585 /* Decide destination address. */
3586 /* RFC2328 Section 13.5 On non-broadcast
3587 networks, delayed Link State Acknowledgment packets must be
3588 unicast separately over each adjacency (i.e., neighbor whose
3589 state is >= Exchange). */
3590 if (oi->type == OSPF_IFTYPE_NBMA)
3591 {
3592 struct ospf_neighbor *nbr;
3593 struct route_node *rn;
3594
3595 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3596 if ((nbr = rn->info) != NULL)
3597 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3598 while (listcount (oi->ls_ack))
3599 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3600 return;
3601 }
3602 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3603 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3604 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3605 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3606 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3607 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
630e4807 3608 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3609 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
718e3744 3610 else
3611 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3612
3613 while (listcount (oi->ls_ack))
3614 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3615}