]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_packet.c
ospfd: Update nsm_change_state to static scope, as it is not called from elsewhere
[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. */
272ca1e3 53const struct message ospf_packet_type_str[] =
718e3744 54{
272ca1e3
DO
55 { OSPF_MSG_HELLO, "Hello" },
56 { OSPF_MSG_DB_DESC, "Database Description" },
57 { OSPF_MSG_LS_REQ, "Link State Request" },
58 { OSPF_MSG_LS_UPD, "Link State Update" },
59 { OSPF_MSG_LS_ACK, "Link State Acknowledgment" },
718e3744 60};
272ca1e3
DO
61const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) /
62 sizeof (ospf_packet_type_str[0]);
718e3744 63
75c8eabb
DO
64/* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of
65 particular types, offset is the "type" field of a packet. */
66static const u_int16_t ospf_packet_minlen[] =
67{
68 0,
69 OSPF_HELLO_MIN_SIZE,
70 OSPF_DB_DESC_MIN_SIZE,
71 OSPF_LS_REQ_MIN_SIZE,
72 OSPF_LS_UPD_MIN_SIZE,
73 OSPF_LS_ACK_MIN_SIZE,
74};
75
4e31de79
DO
76/* Minimum (besides OSPF_LSA_HEADER_SIZE) lengths for LSAs of particular
77 types, offset is the "LSA type" field. */
78static const u_int16_t ospf_lsa_minlen[] =
79{
80 0,
81 OSPF_ROUTER_LSA_MIN_SIZE,
82 OSPF_NETWORK_LSA_MIN_SIZE,
83 OSPF_SUMMARY_LSA_MIN_SIZE,
84 OSPF_SUMMARY_LSA_MIN_SIZE,
85 OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
86 0,
87 OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
88 0,
89 0,
90 0,
91 0,
92};
93
bd5651f0
DO
94/* for ospf_check_auth() */
95static int ospf_check_sum (struct ospf_header *);
96
718e3744 97/* OSPF authentication checking function */
4dadc291 98static int
718e3744 99ospf_auth_type (struct ospf_interface *oi)
100{
101 int auth_type;
102
103 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
104 auth_type = oi->area->auth_type;
105 else
106 auth_type = OSPF_IF_PARAM (oi, auth_type);
107
108 /* Handle case where MD5 key list is not configured aka Cisco */
109 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
110 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
111 return OSPF_AUTH_NULL;
112
113 return auth_type;
114
115}
116
718e3744 117struct ospf_packet *
118ospf_packet_new (size_t size)
119{
120 struct ospf_packet *new;
121
122 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
123 new->s = stream_new (size);
124
125 return new;
126}
127
128void
129ospf_packet_free (struct ospf_packet *op)
130{
131 if (op->s)
132 stream_free (op->s);
133
134 XFREE (MTYPE_OSPF_PACKET, op);
135
136 op = NULL;
137}
138
139struct ospf_fifo *
140ospf_fifo_new ()
141{
142 struct ospf_fifo *new;
143
144 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
145 return new;
146}
147
148/* Add new packet to fifo. */
149void
150ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
151{
152 if (fifo->tail)
153 fifo->tail->next = op;
154 else
155 fifo->head = op;
156
157 fifo->tail = op;
158
159 fifo->count++;
160}
161
aa276fd7
PJ
162/* Add new packet to head of fifo. */
163static void
164ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
165{
166 op->next = fifo->head;
167
168 if (fifo->tail == NULL)
169 fifo->tail = op;
170
171 fifo->head = op;
172
173 fifo->count++;
174}
175
718e3744 176/* Delete first packet from fifo. */
177struct ospf_packet *
178ospf_fifo_pop (struct ospf_fifo *fifo)
179{
180 struct ospf_packet *op;
181
182 op = fifo->head;
183
184 if (op)
185 {
186 fifo->head = op->next;
187
188 if (fifo->head == NULL)
189 fifo->tail = NULL;
190
191 fifo->count--;
192 }
193
194 return op;
195}
196
197/* Return first fifo entry. */
198struct ospf_packet *
199ospf_fifo_head (struct ospf_fifo *fifo)
200{
201 return fifo->head;
202}
203
204/* Flush ospf packet fifo. */
205void
206ospf_fifo_flush (struct ospf_fifo *fifo)
207{
208 struct ospf_packet *op;
209 struct ospf_packet *next;
210
211 for (op = fifo->head; op; op = next)
212 {
213 next = op->next;
214 ospf_packet_free (op);
215 }
216 fifo->head = fifo->tail = NULL;
217 fifo->count = 0;
218}
219
220/* Free ospf packet fifo. */
221void
222ospf_fifo_free (struct ospf_fifo *fifo)
223{
224 ospf_fifo_flush (fifo);
225
226 XFREE (MTYPE_OSPF_FIFO, fifo);
227}
228
229void
230ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
231{
c3eab871 232 if (!oi->obuf)
233 {
234 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
235 "destination %s) called with NULL obuf, ignoring "
236 "(please report this bug)!\n",
237 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
272ca1e3 238 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
c3eab871 239 inet_ntoa (op->dst));
240 return;
241 }
242
718e3744 243 /* Add packet to end of queue. */
244 ospf_fifo_push (oi->obuf, op);
245
246 /* Debug of packet fifo*/
247 /* ospf_fifo_debug (oi->obuf); */
248}
249
aa276fd7
PJ
250static void
251ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
252{
253 if (!oi->obuf)
254 {
255 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
256 "destination %s) called with NULL obuf, ignoring "
257 "(please report this bug)!\n",
258 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
7e0e2cb1 259 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
aa276fd7
PJ
260 inet_ntoa (op->dst));
261 return;
262 }
263
264 /* Add packet to head of queue. */
265 ospf_fifo_push_head (oi->obuf, op);
266
267 /* Debug of packet fifo*/
268 /* ospf_fifo_debug (oi->obuf); */
269}
270
718e3744 271void
272ospf_packet_delete (struct ospf_interface *oi)
273{
274 struct ospf_packet *op;
275
276 op = ospf_fifo_pop (oi->obuf);
277
278 if (op)
279 ospf_packet_free (op);
280}
281
718e3744 282struct ospf_packet *
283ospf_packet_dup (struct ospf_packet *op)
284{
285 struct ospf_packet *new;
286
37163d6d 287 if (stream_get_endp(op->s) != op->length)
08c83671
AS
288 /* XXX size_t */
289 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
290 (u_long)STREAM_SIZE(op->s), op->length);
30961a15 291
292 /* Reserve space for MD5 authentication that may be added later. */
293 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
fa81b713 294 stream_copy (new->s, op->s);
718e3744 295
296 new->dst = op->dst;
297 new->length = op->length;
298
299 return new;
300}
301
86f1fd96 302/* XXX inline */
f63f06da 303static unsigned int
86f1fd96 304ospf_packet_authspace (struct ospf_interface *oi)
305{
306 int auth = 0;
307
308 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
309 auth = OSPF_AUTH_MD5_SIZE;
310
311 return auth;
312}
313
4dadc291 314static unsigned int
718e3744 315ospf_packet_max (struct ospf_interface *oi)
316{
317 int max;
318
86f1fd96 319 max = oi->ifp->mtu - ospf_packet_authspace(oi);
320
68b7339a 321 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
718e3744 322
323 return max;
324}
325
326\f
4dadc291 327static int
2d8223c5 328ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh)
718e3744 329{
c1a03d47 330 MD5_CTX ctx;
718e3744 331 unsigned char digest[OSPF_AUTH_MD5_SIZE];
718e3744 332 struct crypt_key *ck;
718e3744 333 struct ospf_neighbor *nbr;
2d8223c5 334 u_int16_t length = ntohs (ospfh->length);
718e3744 335
718e3744 336 /* Get secret key. */
337 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
338 ospfh->u.crypt.key_id);
339 if (ck == NULL)
340 {
341 zlog_warn ("interface %s: ospf_check_md5 no key %d",
342 IF_NAME (oi), ospfh->u.crypt.key_id);
343 return 0;
344 }
345
346 /* check crypto seqnum. */
347 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
348
349 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
350 {
351 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
352 IF_NAME (oi),
353 ntohl(ospfh->u.crypt.crypt_seqnum),
354 ntohl(nbr->crypt_seqnum));
355 return 0;
356 }
357
358 /* Generate a digest for the ospf packet - their digest + our digest. */
c1a03d47 359 memset(&ctx, 0, sizeof(ctx));
360 MD5Init(&ctx);
2d8223c5 361 MD5Update(&ctx, ospfh, length);
c1a03d47 362 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
363 MD5Final(digest, &ctx);
718e3744 364
365 /* compare the two */
2d8223c5 366 if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE))
718e3744 367 {
368 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
369 IF_NAME (oi));
370 return 0;
371 }
372
373 /* save neighbor's crypt_seqnum */
374 if (nbr)
375 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
376 return 1;
377}
378
379/* This function is called from ospf_write(), it will detect the
380 authentication scheme and if it is MD5, it will change the sequence
381 and update the MD5 digest. */
4dadc291 382static int
718e3744 383ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
384{
385 struct ospf_header *ospfh;
386 unsigned char digest[OSPF_AUTH_MD5_SIZE];
c1a03d47 387 MD5_CTX ctx;
718e3744 388 void *ibuf;
9483e155 389 u_int32_t t;
718e3744 390 struct crypt_key *ck;
3623814a 391 const u_int8_t *auth_key;
718e3744 392
393 ibuf = STREAM_DATA (op->s);
394 ospfh = (struct ospf_header *) ibuf;
395
396 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
397 return 0;
398
399 /* We do this here so when we dup a packet, we don't have to
2518efd1
PJ
400 waste CPU rewriting other headers.
401
402 Note that quagga_time /deliberately/ is not used here */
9483e155 403 t = (time(NULL) & 0xFFFFFFFF);
818e56cf 404 if (t > oi->crypt_seqnum)
405 oi->crypt_seqnum = t;
406 else
407 oi->crypt_seqnum++;
408
9483e155 409 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
718e3744 410
411 /* Get MD5 Authentication key from auth_key list. */
412 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
3623814a 413 auth_key = (const u_int8_t *) "";
718e3744 414 else
415 {
1eb8ef25 416 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
4dadc291 417 auth_key = ck->auth_key;
718e3744 418 }
419
420 /* Generate a digest for the entire packet + our secret key. */
c1a03d47 421 memset(&ctx, 0, sizeof(ctx));
422 MD5Init(&ctx);
423 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
424 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
425 MD5Final(digest, &ctx);
718e3744 426
427 /* Append md5 digest to the end of the stream. */
718e3744 428 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
718e3744 429
430 /* We do *NOT* increment the OSPF header length. */
30961a15 431 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
432
37163d6d 433 if (stream_get_endp(op->s) != op->length)
08c83671
AS
434 /* XXX size_t */
435 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
436 (u_long)stream_get_endp(op->s), op->length);
718e3744 437
438 return OSPF_AUTH_MD5_SIZE;
439}
440
441\f
4dadc291 442static int
718e3744 443ospf_ls_req_timer (struct thread *thread)
444{
445 struct ospf_neighbor *nbr;
446
447 nbr = THREAD_ARG (thread);
448 nbr->t_ls_req = NULL;
449
450 /* Send Link State Request. */
451 if (ospf_ls_request_count (nbr))
452 ospf_ls_req_send (nbr);
453
454 /* Set Link State Request retransmission timer. */
455 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
456
457 return 0;
458}
459
460void
461ospf_ls_req_event (struct ospf_neighbor *nbr)
462{
463 if (nbr->t_ls_req)
464 {
465 thread_cancel (nbr->t_ls_req);
466 nbr->t_ls_req = NULL;
467 }
468 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
469}
470
471/* Cyclic timer function. Fist registered in ospf_nbr_new () in
472 ospf_neighbor.c */
473int
474ospf_ls_upd_timer (struct thread *thread)
475{
476 struct ospf_neighbor *nbr;
477
478 nbr = THREAD_ARG (thread);
479 nbr->t_ls_upd = NULL;
480
481 /* Send Link State Update. */
482 if (ospf_ls_retransmit_count (nbr) > 0)
483 {
52dc7ee6 484 struct list *update;
718e3744 485 struct ospf_lsdb *lsdb;
486 int i;
718e3744 487 int retransmit_interval;
488
718e3744 489 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
490
491 lsdb = &nbr->ls_rxmt;
492 update = list_new ();
493
494 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
495 {
496 struct route_table *table = lsdb->type[i].db;
497 struct route_node *rn;
498
499 for (rn = route_top (table); rn; rn = route_next (rn))
500 {
501 struct ospf_lsa *lsa;
502
503 if ((lsa = rn->info) != NULL)
504 /* Don't retransmit an LSA if we received it within
505 the last RxmtInterval seconds - this is to allow the
506 neighbour a chance to acknowledge the LSA as it may
507 have ben just received before the retransmit timer
508 fired. This is a small tweak to what is in the RFC,
509 but it will cut out out a lot of retransmit traffic
510 - MAG */
2518efd1 511 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
718e3744 512 int2tv (retransmit_interval)) >= 0)
513 listnode_add (update, rn->info);
514 }
515 }
516
517 if (listcount (update) > 0)
518 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
519 list_delete (update);
520 }
521
522 /* Set LS Update retransmission timer. */
523 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
524
525 return 0;
526}
527
528int
529ospf_ls_ack_timer (struct thread *thread)
530{
531 struct ospf_interface *oi;
532
533 oi = THREAD_ARG (thread);
534 oi->t_ls_ack = NULL;
535
536 /* Send Link State Acknowledgment. */
537 if (listcount (oi->ls_ack) > 0)
538 ospf_ls_ack_send_delayed (oi);
539
540 /* Set LS Ack timer. */
541 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
542
543 return 0;
544}
545
0bfeca3f 546#ifdef WANT_OSPF_WRITE_FRAGMENT
5dcbdf82 547static void
6a99f831 548ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
62d8e96a 549 struct msghdr *msg, unsigned int maxdatasize,
37ccfa3d 550 unsigned int mtu, int flags, u_char type)
0bfeca3f 551{
552#define OSPF_WRITE_FRAG_SHIFT 3
6a99f831 553 u_int16_t offset;
62d8e96a 554 struct iovec *iovp;
6a99f831 555 int ret;
0bfeca3f 556
557 assert ( op->length == stream_get_endp(op->s) );
62d8e96a 558 assert (msg->msg_iovlen == 2);
0bfeca3f 559
560 /* we can but try.
561 *
562 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
563 * well as the IP_MF flag, making this all quite pointless.
564 *
565 * However, for a system on which IP_MF is left alone, and ip_id left
566 * alone or else which sets same ip_id for each fragment this might
567 * work, eg linux.
568 *
569 * XXX-TODO: It would be much nicer to have the kernel's use their
570 * existing fragmentation support to do this for us. Bugs/RFEs need to
571 * be raised against the various kernels.
572 */
573
574 /* set More Frag */
575 iph->ip_off |= IP_MF;
576
577 /* ip frag offset is expressed in units of 8byte words */
578 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
579
62d8e96a 580 iovp = &msg->msg_iov[1];
581
0bfeca3f 582 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
583 > maxdatasize )
584 {
585 /* data length of this frag is to next offset value */
62d8e96a 586 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
587 iph->ip_len = iovp->iov_len + sizeof (struct ip);
6a99f831 588 assert (iph->ip_len <= mtu);
0bfeca3f 589
18b12c38 590 sockopt_iphdrincl_swab_htosys (iph);
0bfeca3f 591
6a99f831 592 ret = sendmsg (fd, msg, flags);
0bfeca3f 593
18b12c38 594 sockopt_iphdrincl_swab_systoh (iph);
0bfeca3f 595
596 if (ret < 0)
37ccfa3d 597 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
5dcbdf82 598 " id %d, off %d, len %d, mtu %u failed with %s",
599 inet_ntoa (iph->ip_dst),
600 iph->ip_id,
601 iph->ip_off,
602 iph->ip_len,
603 mtu,
604 safe_strerror (errno));
0bfeca3f 605
37ccfa3d 606 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
607 {
2a42e285 608 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
37ccfa3d 609 iph->ip_id, iph->ip_off, iph->ip_len,
610 inet_ntoa (iph->ip_dst));
611 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
612 {
2a42e285 613 zlog_debug ("-----------------IP Header Dump----------------------");
37ccfa3d 614 ospf_ip_header_dump (iph);
2a42e285 615 zlog_debug ("-----------------------------------------------------");
37ccfa3d 616 }
617 }
618
0bfeca3f 619 iph->ip_off += offset;
9985f83c 620 stream_forward_getp (op->s, iovp->iov_len);
62d8e96a 621 iovp->iov_base = STREAM_PNT (op->s);
0bfeca3f 622 }
623
624 /* setup for final fragment */
62d8e96a 625 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
626 iph->ip_len = iovp->iov_len + sizeof (struct ip);
0bfeca3f 627 iph->ip_off &= (~IP_MF);
628}
629#endif /* WANT_OSPF_WRITE_FRAGMENT */
630
5dcbdf82 631static int
718e3744 632ospf_write (struct thread *thread)
633{
68980084 634 struct ospf *ospf = THREAD_ARG (thread);
718e3744 635 struct ospf_interface *oi;
636 struct ospf_packet *op;
637 struct sockaddr_in sa_dst;
718e3744 638 struct ip iph;
639 struct msghdr msg;
62d8e96a 640 struct iovec iov[2];
68980084 641 u_char type;
642 int ret;
643 int flags = 0;
52dc7ee6 644 struct listnode *node;
0bfeca3f 645#ifdef WANT_OSPF_WRITE_FRAGMENT
68b7339a 646 static u_int16_t ipid = 0;
0bfeca3f 647#endif /* WANT_OSPF_WRITE_FRAGMENT */
6a99f831 648 u_int16_t maxdatasize;
68b7339a 649#define OSPF_WRITE_IPHL_SHIFT 2
718e3744 650
68980084 651 ospf->t_write = NULL;
718e3744 652
68980084 653 node = listhead (ospf->oi_write_q);
718e3744 654 assert (node);
1eb8ef25 655 oi = listgetdata (node);
718e3744 656 assert (oi);
0bfeca3f 657
658#ifdef WANT_OSPF_WRITE_FRAGMENT
68b7339a 659 /* seed ipid static with low order bits of time */
660 if (ipid == 0)
661 ipid = (time(NULL) & 0xffff);
0bfeca3f 662#endif /* WANT_OSPF_WRITE_FRAGMENT */
663
b7fe4141
DO
664 /* convenience - max OSPF data per packet,
665 * and reliability - not more data, than our
666 * socket can accept
667 */
668 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
669 sizeof (struct ip);
68b7339a 670
718e3744 671 /* Get one packet from queue. */
672 op = ospf_fifo_head (oi->obuf);
673 assert (op);
674 assert (op->length >= OSPF_HEADER_SIZE);
675
68980084 676 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
677 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
68b7339a 678 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
679
718e3744 680 /* Rewrite the md5 signature & update the seq */
681 ospf_make_md5_digest (oi, op);
682
37ccfa3d 683 /* Retrieve OSPF packet type. */
684 stream_set_getp (op->s, 1);
685 type = stream_getc (op->s);
686
68b7339a 687 /* reset get pointer */
688 stream_set_getp (op->s, 0);
689
690 memset (&iph, 0, sizeof (struct ip));
718e3744 691 memset (&sa_dst, 0, sizeof (sa_dst));
68b7339a 692
718e3744 693 sa_dst.sin_family = AF_INET;
6f0e3f6e 694#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
718e3744 695 sa_dst.sin_len = sizeof(sa_dst);
6f0e3f6e 696#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
718e3744 697 sa_dst.sin_addr = op->dst;
698 sa_dst.sin_port = htons (0);
699
700 /* Set DONTROUTE flag if dst is unicast. */
701 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
702 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
703 flags = MSG_DONTROUTE;
704
68b7339a 705 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
706 /* it'd be very strange for header to not be 4byte-word aligned but.. */
6c835671 707 if ( sizeof (struct ip)
708 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
68b7339a 709 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
710
718e3744 711 iph.ip_v = IPVERSION;
68980084 712 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
68b7339a 713 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
68b7339a 714
0150c9c9
DB
715#if defined(__DragonFly__)
716 /*
717 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
718 */
719 iph.ip_len = htons(iph.ip_len);
720#endif
721
0bfeca3f 722#ifdef WANT_OSPF_WRITE_FRAGMENT
68b7339a 723 /* XXX-MT: not thread-safe at all..
724 * XXX: this presumes this is only programme sending OSPF packets
725 * otherwise, no guarantee ipid will be unique
726 */
727 iph.ip_id = ++ipid;
0bfeca3f 728#endif /* WANT_OSPF_WRITE_FRAGMENT */
729
718e3744 730 iph.ip_off = 0;
731 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
732 iph.ip_ttl = OSPF_VL_IP_TTL;
733 else
734 iph.ip_ttl = OSPF_IP_TTL;
735 iph.ip_p = IPPROTO_OSPFIGP;
736 iph.ip_sum = 0;
737 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
738 iph.ip_dst.s_addr = op->dst.s_addr;
739
740 memset (&msg, 0, sizeof (msg));
68defd6d 741 msg.msg_name = (caddr_t) &sa_dst;
718e3744 742 msg.msg_namelen = sizeof (sa_dst);
743 msg.msg_iov = iov;
744 msg.msg_iovlen = 2;
745 iov[0].iov_base = (char*)&iph;
68b7339a 746 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
747 iov[1].iov_base = STREAM_PNT (op->s);
718e3744 748 iov[1].iov_len = op->length;
68b7339a 749
750 /* Sadly we can not rely on kernels to fragment packets because of either
751 * IP_HDRINCL and/or multicast destination being set.
752 */
0bfeca3f 753#ifdef WANT_OSPF_WRITE_FRAGMENT
68b7339a 754 if ( op->length > maxdatasize )
62d8e96a 755 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
756 oi->ifp->mtu, flags, type);
0bfeca3f 757#endif /* WANT_OSPF_WRITE_FRAGMENT */
718e3744 758
68b7339a 759 /* send final fragment (could be first) */
18b12c38 760 sockopt_iphdrincl_swab_htosys (&iph);
68980084 761 ret = sendmsg (ospf->fd, &msg, flags);
6b333611 762 sockopt_iphdrincl_swab_systoh (&iph);
718e3744 763
764 if (ret < 0)
083ee9d9 765 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
5dcbdf82 766 "id %d, off %d, len %d, interface %s, mtu %u: %s",
083ee9d9 767 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
5dcbdf82 768 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
718e3744 769
718e3744 770 /* Show debug sending packet. */
771 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
772 {
773 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
774 {
2a42e285 775 zlog_debug ("-----------------------------------------------------");
37ccfa3d 776 ospf_ip_header_dump (&iph);
718e3744 777 stream_set_getp (op->s, 0);
778 ospf_packet_dump (op->s);
779 }
780
2a42e285 781 zlog_debug ("%s sent to [%s] via [%s].",
272ca1e3 782 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
718e3744 783 IF_NAME (oi));
784
785 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
2a42e285 786 zlog_debug ("-----------------------------------------------------");
718e3744 787 }
788
789 /* Now delete packet from queue. */
790 ospf_packet_delete (oi);
791
792 if (ospf_fifo_head (oi->obuf) == NULL)
793 {
794 oi->on_write_q = 0;
68980084 795 list_delete_node (ospf->oi_write_q, node);
718e3744 796 }
797
798 /* If packets still remain in queue, call write thread. */
68980084 799 if (!list_isempty (ospf->oi_write_q))
800 ospf->t_write =
801 thread_add_write (master, ospf_write, ospf, ospf->fd);
718e3744 802
803 return 0;
804}
805
806/* OSPF Hello message read -- RFC2328 Section 10.5. */
4dadc291 807static void
718e3744 808ospf_hello (struct ip *iph, struct ospf_header *ospfh,
809 struct stream * s, struct ospf_interface *oi, int size)
810{
811 struct ospf_hello *hello;
812 struct ospf_neighbor *nbr;
718e3744 813 int old_state;
d3f0d621 814 struct prefix p;
718e3744 815
816 /* increment statistics. */
817 oi->hello_in++;
818
819 hello = (struct ospf_hello *) STREAM_PNT (s);
820
821 /* If Hello is myself, silently discard. */
68980084 822 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
d324181c 823 {
824 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
825 {
2a42e285 826 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
d324181c 827 "dropping.",
272ca1e3 828 LOOKUP (ospf_packet_type_str, ospfh->type),
d324181c 829 inet_ntoa (iph->ip_src));
830 }
831 return;
832 }
718e3744 833
718e3744 834 /* get neighbor prefix. */
835 p.family = AF_INET;
836 p.prefixlen = ip_masklen (hello->network_mask);
837 p.u.prefix4 = iph->ip_src;
838
839 /* Compare network mask. */
840 /* Checking is ignored for Point-to-Point and Virtual link. */
841 if (oi->type != OSPF_IFTYPE_POINTOPOINT
842 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
843 if (oi->address->prefixlen != p.prefixlen)
844 {
13cd3dc1
AS
845 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
846 inet_ntoa(ospfh->router_id), IF_NAME(oi),
847 (int)oi->address->prefixlen, (int)p.prefixlen);
718e3744 848 return;
849 }
850
718e3744 851 /* Compare Router Dead Interval. */
852 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
853 {
08c83671
AS
854 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
855 "(expected %u, but received %u).",
856 inet_ntoa(ospfh->router_id),
857 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
718e3744 858 return;
859 }
860
f9ad937f 861 /* Compare Hello Interval - ignored if fast-hellos are set. */
862 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
863 {
864 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
865 {
08c83671
AS
866 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
867 "(expected %u, but received %u).",
868 inet_ntoa(ospfh->router_id),
869 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
f9ad937f 870 return;
871 }
872 }
873
718e3744 874 if (IS_DEBUG_OSPF_EVENT)
2a42e285 875 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
718e3744 876 inet_ntoa (ospfh->router_id),
877 ospf_options_dump (hello->options));
878
879 /* Compare options. */
880#define REJECT_IF_TBIT_ON 1 /* XXX */
881#ifdef REJECT_IF_TBIT_ON
882 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
883 {
884 /*
885 * This router does not support non-zero TOS.
886 * Drop this Hello packet not to establish neighbor relationship.
887 */
888 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
889 inet_ntoa (ospfh->router_id));
890 return;
891 }
892#endif /* REJECT_IF_TBIT_ON */
893
894#ifdef HAVE_OPAQUE_LSA
68980084 895 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
718e3744 896 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
897 {
898 /*
899 * This router does know the correct usage of O-bit
900 * the bit should be set in DD packet only.
901 */
902 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
903 inet_ntoa (ospfh->router_id));
904#ifdef STRICT_OBIT_USAGE_CHECK
905 return; /* Reject this packet. */
906#else /* STRICT_OBIT_USAGE_CHECK */
907 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
908#endif /* STRICT_OBIT_USAGE_CHECK */
909 }
910#endif /* HAVE_OPAQUE_LSA */
911
912 /* new for NSSA is to ensure that NP is on and E is off */
913
718e3744 914 if (oi->area->external_routing == OSPF_AREA_NSSA)
915 {
916 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
917 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
918 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
919 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
920 {
921 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
922 return;
923 }
924 if (IS_DEBUG_OSPF_NSSA)
2a42e285 925 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
718e3744 926 }
927 else
718e3744 928 /* The setting of the E-bit found in the Hello Packet's Options
929 field must match this area's ExternalRoutingCapability A
930 mismatch causes processing to stop and the packet to be
931 dropped. The setting of the rest of the bits in the Hello
932 Packet's Options field should be ignored. */
933 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
934 CHECK_FLAG (hello->options, OSPF_OPTION_E))
935 {
3aa8d5f9 936 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
937 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
718e3744 938 return;
939 }
718e3744 940
d3f0d621 941 /* get neighbour struct */
942 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
943
944 /* neighbour must be valid, ospf_nbr_get creates if none existed */
945 assert (nbr);
718e3744 946
947 old_state = nbr->state;
948
949 /* Add event to thread. */
57c5c652 950 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
718e3744 951
952 /* RFC2328 Section 9.5.1
953 If the router is not eligible to become Designated Router,
954 (snip) It must also send an Hello Packet in reply to an
955 Hello Packet received from any eligible neighbor (other than
956 the current Designated Router and Backup Designated Router). */
957 if (oi->type == OSPF_IFTYPE_NBMA)
958 if (PRIORITY(oi) == 0 && hello->priority > 0
959 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
960 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
961 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
962 OSPF_HELLO_REPLY_DELAY);
963
964 /* on NBMA network type, it happens to receive bidirectional Hello packet
965 without advance 1-Way Received event.
966 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
967 if (oi->type == OSPF_IFTYPE_NBMA &&
968 (old_state == NSM_Down || old_state == NSM_Attempt))
969 {
57c5c652 970 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
718e3744 971 nbr->priority = hello->priority;
972 nbr->d_router = hello->d_router;
973 nbr->bd_router = hello->bd_router;
974 return;
975 }
976
68980084 977 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
718e3744 978 size - OSPF_HELLO_MIN_SIZE))
979 {
57c5c652 980 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
718e3744 981 nbr->options |= hello->options;
982 }
983 else
984 {
57c5c652 985 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
718e3744 986 /* Set neighbor information. */
987 nbr->priority = hello->priority;
988 nbr->d_router = hello->d_router;
989 nbr->bd_router = hello->bd_router;
990 return;
991 }
992
993 /* If neighbor itself declares DR and no BDR exists,
994 cause event BackupSeen */
995 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
996 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
997 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
998
999 /* neighbor itself declares BDR. */
1000 if (oi->state == ISM_Waiting &&
1001 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
1002 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
1003
1004 /* had not previously. */
1005 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
1006 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
1007 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
1008 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
1009 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1010
1011 /* had not previously. */
1012 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
1013 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
1014 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
1015 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
1016 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1017
1018 /* Neighbor priority check. */
1019 if (nbr->priority >= 0 && nbr->priority != hello->priority)
1020 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1021
1022 /* Set neighbor information. */
1023 nbr->priority = hello->priority;
1024 nbr->d_router = hello->d_router;
1025 nbr->bd_router = hello->bd_router;
1026}
1027
1028/* Save DD flags/options/Seqnum received. */
4dadc291 1029static void
718e3744 1030ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1031 struct ospf_db_desc *dd)
1032{
1033 nbr->last_recv.flags = dd->flags;
1034 nbr->last_recv.options = dd->options;
1035 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1036}
1037
1038/* Process rest of DD packet. */
1039static void
1040ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1041 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1042 u_int16_t size)
1043{
1044 struct ospf_lsa *new, *find;
1045 struct lsa_header *lsah;
1046
9985f83c 1047 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
718e3744 1048 for (size -= OSPF_DB_DESC_MIN_SIZE;
1049 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1050 {
1051 lsah = (struct lsa_header *) STREAM_PNT (s);
9985f83c 1052 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
718e3744 1053
1054 /* Unknown LS type. */
1055 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1056 {
bec595ad 1057 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
718e3744 1058 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1059 return;
1060 }
1061
1062#ifdef HAVE_OPAQUE_LSA
1063 if (IS_OPAQUE_LSA (lsah->type)
1064 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1065 {
1066 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1067 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1068 return;
1069 }
1070#endif /* HAVE_OPAQUE_LSA */
1071
1072 switch (lsah->type)
1073 {
1074 case OSPF_AS_EXTERNAL_LSA:
1075#ifdef HAVE_OPAQUE_LSA
1076 case OSPF_OPAQUE_AS_LSA:
1077#endif /* HAVE_OPAQUE_LSA */
718e3744 1078 /* Check for stub area. Reject if AS-External from stub but
1079 allow if from NSSA. */
1080 if (oi->area->external_routing == OSPF_AREA_STUB)
718e3744 1081 {
1082 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1083 lsah->type, inet_ntoa (lsah->id),
1084 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1085 "STUB" : "NSSA");
1086 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1087 return;
1088 }
1089 break;
1090 default:
1091 break;
1092 }
1093
1094 /* Create LS-request object. */
1095 new = ospf_ls_request_new (lsah);
1096
1097 /* Lookup received LSA, then add LS request list. */
1098 find = ospf_lsa_lookup_by_header (oi->area, lsah);
f0894cf8
PJ
1099
1100 /* ospf_lsa_more_recent is fine with NULL pointers */
1101 switch (ospf_lsa_more_recent (find, new))
1102 {
1103 case -1:
1104 /* Neighbour has a more recent LSA, we must request it */
1105 ospf_ls_request_add (nbr, new);
1106 case 0:
1107 /* If we have a copy of this LSA, it's either less recent
1108 * and we're requesting it from neighbour (the case above), or
1109 * it's as recent and we both have same copy (this case).
1110 *
1111 * In neither of these two cases is there any point in
1112 * describing our copy of the LSA to the neighbour in a
1113 * DB-Summary packet, if we're still intending to do so.
1114 *
1115 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1116 * backward compatible optimisation to OSPF DB Exchange /
1117 * DB Description process implemented here.
1118 */
1119 if (find)
1120 ospf_lsdb_delete (&nbr->db_sum, find);
1121 ospf_lsa_discard (new);
1122 break;
1123 default:
1124 /* We have the more recent copy, nothing specific to do:
1125 * - no need to request neighbours stale copy
1126 * - must leave DB summary list copy alone
1127 */
1128 if (IS_DEBUG_OSPF_EVENT)
1129 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1130 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1131 ospf_lsa_discard (new);
1132 }
718e3744 1133 }
1134
1135 /* Master */
1136 if (IS_SET_DD_MS (nbr->dd_flags))
1137 {
1138 nbr->dd_seqnum++;
8dd24ee6
PJ
1139
1140 /* Both sides have no More, then we're done with Exchange */
718e3744 1141 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1142 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1143 else
718e3744 1144 ospf_db_desc_send (nbr);
1145 }
1146 /* Slave */
1147 else
1148 {
1149 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1150
8dd24ee6
PJ
1151 /* Send DD packet in reply.
1152 *
1153 * Must be done to acknowledge the Master's DD, regardless of
1154 * whether we have more LSAs ourselves to describe.
1155 *
1156 * This function will clear the 'More' bit, if after this DD
1157 * we have no more LSAs to describe to the master..
1158 */
718e3744 1159 ospf_db_desc_send (nbr);
8dd24ee6
PJ
1160
1161 /* Slave can raise ExchangeDone now, if master is also done */
1162 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1163 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
718e3744 1164 }
8dd24ee6 1165
718e3744 1166 /* Save received neighbor values from DD. */
1167 ospf_db_desc_save_current (nbr, dd);
1168}
1169
4dadc291 1170static int
718e3744 1171ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1172{
1173 /* Is DD duplicated? */
1174 if (dd->options == nbr->last_recv.options &&
1175 dd->flags == nbr->last_recv.flags &&
1176 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1177 return 1;
1178
1179 return 0;
1180}
1181
1182/* OSPF Database Description message read -- RFC2328 Section 10.6. */
3aa8d5f9 1183static void
718e3744 1184ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1185 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1186{
1187 struct ospf_db_desc *dd;
1188 struct ospf_neighbor *nbr;
1189
1190 /* Increment statistics. */
1191 oi->db_desc_in++;
1192
1193 dd = (struct ospf_db_desc *) STREAM_PNT (s);
d363df2c 1194
d3f0d621 1195 nbr = ospf_nbr_lookup (oi, iph, ospfh);
718e3744 1196 if (nbr == NULL)
1197 {
1198 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1199 inet_ntoa (ospfh->router_id));
1200 return;
1201 }
1202
1203 /* Check MTU. */
ba682537 1204 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1205 (ntohs (dd->mtu) > oi->ifp->mtu))
718e3744 1206 {
3aa8d5f9 1207 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1208 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1209 IF_NAME (oi), oi->ifp->mtu);
718e3744 1210 return;
1211 }
1212
d363df2c 1213 /*
1214 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1215 * required. In fact at least JunOS sends DD packets with P bit clear.
1216 * Until proper solution is developped, this hack should help.
1217 *
1218 * Update: According to the RFCs, N bit is specified /only/ for Hello
1219 * options, unfortunately its use in DD options is not specified. Hence some
1220 * implementations follow E-bit semantics and set it in DD options, and some
1221 * treat it as unspecified and hence follow the directive "default for
1222 * options is clear", ie unset.
1223 *
1224 * Reset the flag, as ospfd follows E-bit semantics.
1225 */
1226 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1227 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1228 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1229 {
1230 if (IS_DEBUG_OSPF_EVENT)
1210fa66 1231 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
d363df2c 1232 inet_ntoa (nbr->router_id) );
1233 SET_FLAG (dd->options, OSPF_OPTION_NP);
1234 }
d363df2c 1235
718e3744 1236#ifdef REJECT_IF_TBIT_ON
1237 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1238 {
1239 /*
1240 * In Hello protocol, optional capability must have checked
1241 * to prevent this T-bit enabled router be my neighbor.
1242 */
1243 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1244 return;
1245 }
1246#endif /* REJECT_IF_TBIT_ON */
1247
1248#ifdef HAVE_OPAQUE_LSA
1249 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
68980084 1250 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
718e3744 1251 {
1252 /*
1253 * This node is not configured to handle O-bit, for now.
1254 * Clear it to ignore unsupported capability proposed by neighbor.
1255 */
1256 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1257 }
1258#endif /* HAVE_OPAQUE_LSA */
1259
57c5c652
PJ
1260 /* Add event to thread. */
1261 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1262
718e3744 1263 /* Process DD packet by neighbor status. */
1264 switch (nbr->state)
1265 {
1266 case NSM_Down:
1267 case NSM_Attempt:
1268 case NSM_TwoWay:
bec595ad 1269 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
3aa8d5f9 1270 inet_ntoa(nbr->router_id),
718e3744 1271 LOOKUP (ospf_nsm_state_msg, nbr->state));
1272 break;
1273 case NSM_Init:
1274 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1275 /* If the new state is ExStart, the processing of the current
1276 packet should then continue in this new state by falling
1277 through to case ExStart below. */
1278 if (nbr->state != NSM_ExStart)
1279 break;
1280 case NSM_ExStart:
1281 /* Initial DBD */
1282 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1283 (size == OSPF_DB_DESC_MIN_SIZE))
1284 {
68980084 1285 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
718e3744 1286 {
1287 /* We're Slave---obey */
17eaa728 1288 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
3aa8d5f9 1289 inet_ntoa(nbr->router_id));
718e3744 1290 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
8dd24ee6
PJ
1291
1292 /* Reset I/MS */
1293 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
718e3744 1294 }
1295 else
1296 {
1297 /* We're Master, ignore the initial DBD from Slave */
6d45276f 1298 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
3aa8d5f9 1299 "ignoring.", inet_ntoa(nbr->router_id));
718e3744 1300 break;
1301 }
1302 }
1303 /* Ack from the Slave */
1304 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1305 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
68980084 1306 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
718e3744 1307 {
17eaa728 1308 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
3aa8d5f9 1309 inet_ntoa(nbr->router_id));
8dd24ee6
PJ
1310 /* Reset I, leaving MS */
1311 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
718e3744 1312 }
1313 else
1314 {
3aa8d5f9 1315 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1316 inet_ntoa(nbr->router_id));
718e3744 1317 break;
1318 }
1319
1320 /* This is where the real Options are saved */
1321 nbr->options = dd->options;
1322
1323#ifdef HAVE_OPAQUE_LSA
68980084 1324 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
718e3744 1325 {
1326 if (IS_DEBUG_OSPF_EVENT)
2a42e285 1327 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
718e3744 1328 inet_ntoa (nbr->router_id),
1329 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1330
1331 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1332 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1333 {
6d45276f 1334 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1335 "Opaque-LSAs cannot be reliably advertised "
1336 "in this network.",
1337 inet_ntoa (nbr->router_id));
718e3744 1338 /* This situation is undesirable, but not a real error. */
1339 }
1340 }
1341#endif /* HAVE_OPAQUE_LSA */
1342
1343 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1344
1345 /* continue processing rest of packet. */
1346 ospf_db_desc_proc (s, oi, nbr, dd, size);
1347 break;
1348 case NSM_Exchange:
1349 if (ospf_db_desc_is_dup (dd, nbr))
1350 {
1351 if (IS_SET_DD_MS (nbr->dd_flags))
1352 /* Master: discard duplicated DD packet. */
6d45276f 1353 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
3aa8d5f9 1354 inet_ntoa (nbr->router_id));
718e3744 1355 else
1356 /* Slave: cause to retransmit the last Database Description. */
1357 {
6d45276f 1358 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
3aa8d5f9 1359 inet_ntoa (nbr->router_id));
718e3744 1360 ospf_db_desc_resend (nbr);
1361 }
1362 break;
1363 }
1364
1365 /* Otherwise DD packet should be checked. */
1366 /* Check Master/Slave bit mismatch */
1367 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1368 {
3aa8d5f9 1369 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1370 inet_ntoa(nbr->router_id));
718e3744 1371 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1372 if (IS_DEBUG_OSPF_EVENT)
2a42e285 1373 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
3aa8d5f9 1374 dd->flags, nbr->dd_flags);
718e3744 1375 break;
1376 }
1377
1378 /* Check initialize bit is set. */
1379 if (IS_SET_DD_I (dd->flags))
1380 {
6d45276f 1381 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
3aa8d5f9 1382 inet_ntoa(nbr->router_id));
718e3744 1383 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1384 break;
1385 }
1386
1387 /* Check DD Options. */
1388 if (dd->options != nbr->options)
1389 {
1390#ifdef ORIGINAL_CODING
1391 /* Save the new options for debugging */
1392 nbr->options = dd->options;
1393#endif /* ORIGINAL_CODING */
3aa8d5f9 1394 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1395 inet_ntoa(nbr->router_id));
718e3744 1396 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1397 break;
1398 }
1399
1400 /* Check DD sequence number. */
1401 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1402 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1403 (!IS_SET_DD_MS (nbr->dd_flags) &&
1404 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1405 {
3aa8d5f9 1406 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1407 inet_ntoa(nbr->router_id));
718e3744 1408 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1409 break;
1410 }
1411
1412 /* Continue processing rest of packet. */
1413 ospf_db_desc_proc (s, oi, nbr, dd, size);
1414 break;
1415 case NSM_Loading:
1416 case NSM_Full:
1417 if (ospf_db_desc_is_dup (dd, nbr))
1418 {
1419 if (IS_SET_DD_MS (nbr->dd_flags))
1420 {
1421 /* Master should discard duplicate DD packet. */
6d45276f 1422 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1423 "packet discarded.",
3aa8d5f9 1424 inet_ntoa(nbr->router_id));
718e3744 1425 break;
1426 }
1427 else
1428 {
1429 struct timeval t, now;
2518efd1 1430 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
718e3744 1431 t = tv_sub (now, nbr->last_send_ts);
1432 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1433 {
1434 /* In states Loading and Full the slave must resend
1435 its last Database Description packet in response to
1436 duplicate Database Description packets received
1437 from the master. For this reason the slave must
1438 wait RouterDeadInterval seconds before freeing the
1439 last Database Description packet. Reception of a
1440 Database Description packet from the master after
1441 this interval will generate a SeqNumberMismatch
1442 neighbor event. RFC2328 Section 10.8 */
1443 ospf_db_desc_resend (nbr);
1444 break;
1445 }
1446 }
1447 }
1448
1449 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1450 break;
1451 default:
3aa8d5f9 1452 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1453 inet_ntoa(nbr->router_id), nbr->state);
718e3744 1454 break;
1455 }
1456}
1457
1458#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1459
1460/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
4dadc291 1461static void
718e3744 1462ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1463 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1464{
1465 struct ospf_neighbor *nbr;
1466 u_int32_t ls_type;
1467 struct in_addr ls_id;
1468 struct in_addr adv_router;
1469 struct ospf_lsa *find;
52dc7ee6 1470 struct list *ls_upd;
6c835671 1471 unsigned int length;
718e3744 1472
1473 /* Increment statistics. */
1474 oi->ls_req_in++;
1475
d3f0d621 1476 nbr = ospf_nbr_lookup (oi, iph, ospfh);
718e3744 1477 if (nbr == NULL)
1478 {
1479 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1480 inet_ntoa (ospfh->router_id));
1481 return;
1482 }
1483
57c5c652
PJ
1484 /* Add event to thread. */
1485 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1486
718e3744 1487 /* Neighbor State should be Exchange or later. */
1488 if (nbr->state != NSM_Exchange &&
1489 nbr->state != NSM_Loading &&
1490 nbr->state != NSM_Full)
1491 {
bec595ad 1492 zlog_warn ("Link State Request received from %s: "
1493 "Neighbor state is %s, packet discarded.",
1494 inet_ntoa (ospfh->router_id),
718e3744 1495 LOOKUP (ospf_nsm_state_msg, nbr->state));
1496 return;
1497 }
1498
1499 /* Send Link State Update for ALL requested LSAs. */
1500 ls_upd = list_new ();
1501 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1502
1503 while (size >= OSPF_LSA_KEY_SIZE)
1504 {
1505 /* Get one slice of Link State Request. */
1506 ls_type = stream_getl (s);
1507 ls_id.s_addr = stream_get_ipv4 (s);
1508 adv_router.s_addr = stream_get_ipv4 (s);
1509
1510 /* Verify LSA type. */
1511 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1512 {
1513 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1514 list_delete (ls_upd);
1515 return;
1516 }
1517
1518 /* Search proper LSA in LSDB. */
1519 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1520 if (find == NULL)
1521 {
1522 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1523 list_delete (ls_upd);
1524 return;
1525 }
1526
86f1fd96 1527 /* Packet overflows MTU size, send immediately. */
1528 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
718e3744 1529 {
1530 if (oi->type == OSPF_IFTYPE_NBMA)
1531 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1532 else
1533 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1534
1535 /* Only remove list contents. Keep ls_upd. */
1536 list_delete_all_node (ls_upd);
1537
1538 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1539 }
1540
1541 /* Append LSA to update list. */
1542 listnode_add (ls_upd, find);
1543 length += ntohs (find->data->length);
1544
1545 size -= OSPF_LSA_KEY_SIZE;
1546 }
1547
1548 /* Send rest of Link State Update. */
1549 if (listcount (ls_upd) > 0)
1550 {
1551 if (oi->type == OSPF_IFTYPE_NBMA)
1552 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1553 else
1554 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1555
1556 list_delete (ls_upd);
1557 }
1558 else
1559 list_free (ls_upd);
1560}
1561
1562/* Get the list of LSAs from Link State Update packet.
1563 And process some validation -- RFC2328 Section 13. (1)-(2). */
52dc7ee6 1564static struct list *
718e3744 1565ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1566 struct ospf_interface *oi, size_t size)
1567{
1568 u_int16_t count, sum;
1569 u_int32_t length;
1570 struct lsa_header *lsah;
1571 struct ospf_lsa *lsa;
52dc7ee6 1572 struct list *lsas;
718e3744 1573
1574 lsas = list_new ();
1575
1576 count = stream_getl (s);
1577 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1578
1579 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
9985f83c 1580 size -= length, stream_forward_getp (s, length), count--)
718e3744 1581 {
1582 lsah = (struct lsa_header *) STREAM_PNT (s);
1583 length = ntohs (lsah->length);
1584
1585 if (length > size)
1586 {
1587 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1588 break;
1589 }
1590
1591 /* Validate the LSA's LS checksum. */
1592 sum = lsah->checksum;
d8a4e42b 1593 if (! ospf_lsa_checksum_valid (lsah))
718e3744 1594 {
223da1a9
JF
1595 /* (bug #685) more details in a one-line message make it possible
1596 * to identify problem source on the one hand and to have a better
1597 * chance to compress repeated messages in syslog on the other */
1598 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1599 sum, lsah->checksum, inet_ntoa (lsah->id),
1600 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1601 inet_ntoa (lsah->adv_router));
718e3744 1602 continue;
1603 }
1604
1605 /* Examine the LSA's LS type. */
1606 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1607 {
1608 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1609 continue;
1610 }
1611
1612 /*
1613 * What if the received LSA's age is greater than MaxAge?
1614 * Treat it as a MaxAge case -- endo.
1615 */
1616 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1617 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1618
1619#ifdef HAVE_OPAQUE_LSA
1620 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1621 {
1622#ifdef STRICT_OBIT_USAGE_CHECK
1623 if ((IS_OPAQUE_LSA(lsah->type) &&
1624 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1625 || (! IS_OPAQUE_LSA(lsah->type) &&
1626 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1627 {
1628 /*
1629 * This neighbor must know the exact usage of O-bit;
1630 * the bit will be set in Type-9,10,11 LSAs only.
1631 */
1632 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1633 continue;
1634 }
1635#endif /* STRICT_OBIT_USAGE_CHECK */
1636
1637 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1638 if (lsah->type == OSPF_OPAQUE_AS_LSA
1639 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1640 {
1641 if (IS_DEBUG_OSPF_EVENT)
2a42e285 1642 zlog_debug ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
718e3744 1643 continue;
1644 }
1645 }
1646 else if (IS_OPAQUE_LSA(lsah->type))
1647 {
1648 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1649 continue;
1650 }
1651#endif /* HAVE_OPAQUE_LSA */
1652
1653 /* Create OSPF LSA instance. */
1654 lsa = ospf_lsa_new ();
1655
1656 /* We may wish to put some error checking if type NSSA comes in
1657 and area not in NSSA mode */
1658 switch (lsah->type)
1659 {
1660 case OSPF_AS_EXTERNAL_LSA:
1661#ifdef HAVE_OPAQUE_LSA
1662 case OSPF_OPAQUE_AS_LSA:
1663 lsa->area = NULL;
1664 break;
1665 case OSPF_OPAQUE_LINK_LSA:
1666 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1667 /* Fallthrough */
1668#endif /* HAVE_OPAQUE_LSA */
1669 default:
1670 lsa->area = oi->area;
1671 break;
1672 }
1673
1674 lsa->data = ospf_lsa_data_new (length);
1675 memcpy (lsa->data, lsah, length);
1676
1677 if (IS_DEBUG_OSPF_EVENT)
2a42e285 1678 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
718e3744 1679 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1680 listnode_add (lsas, lsa);
1681 }
1682
1683 return lsas;
1684}
1685
1686/* Cleanup Update list. */
4dadc291 1687static void
52dc7ee6 1688ospf_upd_list_clean (struct list *lsas)
718e3744 1689{
1eb8ef25 1690 struct listnode *node, *nnode;
718e3744 1691 struct ospf_lsa *lsa;
1692
1eb8ef25 1693 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1694 ospf_lsa_discard (lsa);
718e3744 1695
1696 list_delete (lsas);
1697}
1698
1699/* OSPF Link State Update message read -- RFC2328 Section 13. */
4dadc291 1700static void
718e3744 1701ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1702 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1703{
1704 struct ospf_neighbor *nbr;
52dc7ee6 1705 struct list *lsas;
1eb8ef25 1706 struct listnode *node, *nnode;
718e3744 1707 struct ospf_lsa *lsa = NULL;
1708 /* unsigned long ls_req_found = 0; */
1709
1710 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1711
1712 /* Increment statistics. */
1713 oi->ls_upd_in++;
1714
1715 /* Check neighbor. */
d3f0d621 1716 nbr = ospf_nbr_lookup (oi, iph, ospfh);
718e3744 1717 if (nbr == NULL)
1718 {
1719 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1720 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1721 return;
1722 }
1723
57c5c652
PJ
1724 /* Add event to thread. */
1725 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1726
718e3744 1727 /* Check neighbor state. */
1728 if (nbr->state < NSM_Exchange)
1729 {
3aa8d5f9 1730 zlog_warn ("Link State Update: "
1731 "Neighbor[%s] state %s is less than Exchange",
1732 inet_ntoa (ospfh->router_id),
1733 LOOKUP(ospf_nsm_state_msg, nbr->state));
718e3744 1734 return;
1735 }
1736
1737 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1738 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1739 * of section 13.
1740 */
1741 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1742
1743#ifdef HAVE_OPAQUE_LSA
718e3744 1744 /*
1745 * If self-originated Opaque-LSAs that have flooded before restart
1746 * are contained in the received LSUpd message, corresponding LSReq
1747 * messages to be sent may have to be modified.
1748 * To eliminate possible race conditions such that flushing and normal
1749 * updating for the same LSA would take place alternately, this trick
1750 * must be done before entering to the loop below.
1751 */
69310a67 1752 /* XXX: Why is this Opaque specific? Either our core code is deficient
1753 * and this should be fixed generally, or Opaque is inventing strawman
1754 * problems */
718e3744 1755 ospf_opaque_adjust_lsreq (nbr, lsas);
1756#endif /* HAVE_OPAQUE_LSA */
1757
1758#define DISCARD_LSA(L,N) {\
1759 if (IS_DEBUG_OSPF_EVENT) \
2a42e285 1760 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
718e3744 1761 ospf_lsa_discard (L); \
1762 continue; }
1763
f92c57f8
AC
1764 /* Process each LSA received in the one packet.
1765 *
1766 * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
1767 * text below are from the stepsin RFC 2328, Section 13.
1768 */
1eb8ef25 1769 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
718e3744 1770 {
1771 struct ospf_lsa *ls_ret, *current;
1772 int ret = 1;
1773
718e3744 1774 if (IS_DEBUG_OSPF_NSSA)
1775 {
1776 char buf1[INET_ADDRSTRLEN];
1777 char buf2[INET_ADDRSTRLEN];
1778 char buf3[INET_ADDRSTRLEN];
1779
2a42e285 1780 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
718e3744 1781 lsa->data->type,
1782 inet_ntop (AF_INET, &ospfh->router_id,
1783 buf1, INET_ADDRSTRLEN),
1784 inet_ntop (AF_INET, &lsa->data->id,
1785 buf2, INET_ADDRSTRLEN),
1786 inet_ntop (AF_INET, &lsa->data->adv_router,
1787 buf3, INET_ADDRSTRLEN));
1788 }
718e3744 1789
1790 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1791
f92c57f8 1792 /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
718e3744 1793
f92c57f8 1794 /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
718e3744 1795
f92c57f8 1796 /* (3) Do not take in AS External LSAs if we are a stub or NSSA. */
718e3744 1797
1798 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1799
1800 /* Do take in Type-7's if we are an NSSA */
1801
1802 /* If we are also an ABR, later translate them to a Type-5 packet */
1803
1804 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1805 translate them to a separate Type-5 packet. */
1806
1807 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1808 /* Reject from STUB or NSSA */
1809 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1810 {
718e3744 1811 if (IS_DEBUG_OSPF_NSSA)
2a42e285 1812 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
2cd754de 1813 DISCARD_LSA (lsa, 1);
718e3744 1814 }
1815
718e3744 1816 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1817 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1818 {
718e3744 1819 if (IS_DEBUG_OSPF_NSSA)
2a42e285 1820 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
2cd754de 1821 DISCARD_LSA (lsa,2);
718e3744 1822 }
718e3744 1823
1824 /* Find the LSA in the current database. */
1825
1826 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1827
f92c57f8 1828 /* (4) If the LSA's LS age is equal to MaxAge, and there is currently
718e3744 1829 no instance of the LSA in the router's link state database,
1830 and none of router's neighbors are in states Exchange or Loading,
f92c57f8 1831 then take the following actions: */
718e3744 1832
1833 if (IS_LSA_MAXAGE (lsa) && !current &&
68980084 1834 (ospf_nbr_count (oi, NSM_Exchange) +
1835 ospf_nbr_count (oi, NSM_Loading)) == 0)
718e3744 1836 {
f92c57f8 1837 /* (4a) Response Link State Acknowledgment. */
718e3744 1838 ospf_ls_ack_send (nbr, lsa);
1839
f92c57f8 1840 /* (4b) Discard LSA. */
faf98758
AB
1841 if (IS_DEBUG_OSPF (lsa, LSA))
1842 {
1843 zlog_debug ("Link State Update[%s]: LS age is equal to MaxAge.",
1844 dump_lsa_key(lsa));
1845 }
718e3744 1846 DISCARD_LSA (lsa, 3);
1847 }
1848
1849#ifdef HAVE_OPAQUE_LSA
1850 if (IS_OPAQUE_LSA (lsa->data->type)
68980084 1851 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
718e3744 1852 {
1853 /*
1854 * Even if initial flushing seems to be completed, there might
1855 * be a case that self-originated LSA with MaxAge still remain
1856 * in the routing domain.
1857 * Just send an LSAck message to cease retransmission.
1858 */
1859 if (IS_LSA_MAXAGE (lsa))
1860 {
1861 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1862 ospf_ls_ack_send (nbr, lsa);
1863 ospf_lsa_discard (lsa);
1864
1865 if (current != NULL && ! IS_LSA_MAXAGE (current))
1866 ospf_opaque_lsa_refresh_schedule (current);
1867 continue;
1868 }
1869
1870 /*
1871 * If an instance of self-originated Opaque-LSA is not found
1872 * in the LSDB, there are some possible cases here.
1873 *
1874 * 1) This node lost opaque-capability after restart.
1875 * 2) Else, a part of opaque-type is no more supported.
1876 * 3) Else, a part of opaque-id is no more supported.
1877 *
1878 * Anyway, it is still this node's responsibility to flush it.
1879 * Otherwise, the LSA instance remains in the routing domain
1880 * until its age reaches to MaxAge.
1881 */
69310a67 1882 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
718e3744 1883 if (current == NULL)
1884 {
1885 if (IS_DEBUG_OSPF_EVENT)
69310a67 1886 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1887 "not found in the LSDB.", dump_lsa_key (lsa));
718e3744 1888
1889 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
69310a67 1890
1891 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1892 ospf_ls_ack_send (nbr, lsa);
1893
718e3744 1894 continue;
1895 }
1896 }
1897#endif /* HAVE_OPAQUE_LSA */
69310a67 1898
cb05eb28 1899 /* It might be happen that received LSA is self-originated network LSA, but
f92c57f8 1900 * router ID is changed. So, we should check if LSA is a network-LSA whose
cb05eb28 1901 * Link State ID is one of the router's own IP interface addresses but whose
1902 * Advertising Router is not equal to the router's own Router ID
1903 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1904 */
1905
1906 if(lsa->data->type == OSPF_NETWORK_LSA)
1907 {
1eb8ef25 1908 struct listnode *oinode, *oinnode;
1909 struct ospf_interface *out_if;
cb05eb28 1910 int Flag = 0;
1911
1eb8ef25 1912 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
cb05eb28 1913 {
cb05eb28 1914 if(out_if == NULL)
1915 break;
1916
1917 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1918 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1919 {
1920 if(out_if->network_lsa_self)
1921 {
1922 ospf_lsa_flush_area(lsa,out_if->area);
1923 if(IS_DEBUG_OSPF_EVENT)
2a42e285 1924 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
cb05eb28 1925 lsa, (int) lsa->data->type);
1926 ospf_lsa_discard (lsa);
1927 Flag = 1;
1928 }
1929 break;
1930 }
1931 }
1932 if(Flag)
1933 continue;
1934 }
718e3744 1935
1936 /* (5) Find the instance of this LSA that is currently contained
1937 in the router's link state database. If there is no
1938 database copy, or the received LSA is more recent than
f92c57f8
AC
1939 the database copy the following steps must be performed.
1940 (The sub steps from RFC 2328 section 13 step (5) will be performed in
1941 ospf_flood() ) */
718e3744 1942
1943 if (current == NULL ||
1944 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1945 {
1946 /* Actual flooding procedure. */
68980084 1947 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
718e3744 1948 DISCARD_LSA (lsa, 4);
1949 continue;
1950 }
1951
1952 /* (6) Else, If there is an instance of the LSA on the sending
1953 neighbor's Link state request list, an error has occurred in
1954 the Database Exchange process. In this case, restart the
1955 Database Exchange process by generating the neighbor event
1956 BadLSReq for the sending neighbor and stop processing the
1957 Link State Update packet. */
1958
1959 if (ospf_ls_request_lookup (nbr, lsa))
1960 {
1961 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
3aa8d5f9 1962 zlog_warn("LSA[%s] instance exists on Link state request list",
1963 dump_lsa_key(lsa));
718e3744 1964
1965 /* Clean list of LSAs. */
1966 ospf_upd_list_clean (lsas);
1967 /* this lsa is not on lsas list already. */
1968 ospf_lsa_discard (lsa);
718e3744 1969 return;
1970 }
1971
1972 /* If the received LSA is the same instance as the database copy
1973 (i.e., neither one is more recent) the following two steps
1974 should be performed: */
1975
1976 if (ret == 0)
1977 {
1978 /* If the LSA is listed in the Link state retransmission list
1979 for the receiving adjacency, the router itself is expecting
1980 an acknowledgment for this LSA. The router should treat the
1981 received LSA as an acknowledgment by removing the LSA from
1982 the Link state retransmission list. This is termed an
1983 "implied acknowledgment". */
1984
1985 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1986
1987 if (ls_ret != NULL)
1988 {
1989 ospf_ls_retransmit_delete (nbr, ls_ret);
1990
1991 /* Delayed acknowledgment sent if advertisement received
1992 from Designated Router, otherwise do nothing. */
1993 if (oi->state == ISM_Backup)
1994 if (NBR_IS_DR (nbr))
1995 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1996
1997 DISCARD_LSA (lsa, 5);
1998 }
1999 else
2000 /* Acknowledge the receipt of the LSA by sending a
2001 Link State Acknowledgment packet back out the receiving
2002 interface. */
2003 {
2004 ospf_ls_ack_send (nbr, lsa);
2005 DISCARD_LSA (lsa, 6);
2006 }
2007 }
2008
2009 /* The database copy is more recent. If the database copy
2010 has LS age equal to MaxAge and LS sequence number equal to
2011 MaxSequenceNumber, simply discard the received LSA without
2012 acknowledging it. (In this case, the LSA's LS sequence number is
2013 wrapping, and the MaxSequenceNumber LSA must be completely
2014 flushed before any new LSA instance can be introduced). */
2015
2016 else if (ret > 0) /* Database copy is more recent */
2017 {
2018 if (IS_LSA_MAXAGE (current) &&
2019 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
2020 {
2021 DISCARD_LSA (lsa, 7);
2022 }
2023 /* Otherwise, as long as the database copy has not been sent in a
2024 Link State Update within the last MinLSArrival seconds, send the
2025 database copy back to the sending neighbor, encapsulated within
2026 a Link State Update Packet. The Link State Update Packet should
2027 be sent directly to the neighbor. In so doing, do not put the
2028 database copy of the LSA on the neighbor's link state
2029 retransmission list, and do not acknowledge the received (less
2030 recent) LSA instance. */
2031 else
2032 {
2033 struct timeval now;
2034
2518efd1 2035 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
718e3744 2036
2037 if (tv_cmp (tv_sub (now, current->tv_orig),
2c9f8e36 2038 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
718e3744 2039 /* Trap NSSA type later.*/
2040 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2041 DISCARD_LSA (lsa, 8);
2042 }
2043 }
2044 }
2cd754de
PJ
2045#undef DISCARD_LSA
2046
718e3744 2047 assert (listcount (lsas) == 0);
2048 list_delete (lsas);
2049}
2050
2051/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
4dadc291 2052static void
718e3744 2053ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2054 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2055{
2056 struct ospf_neighbor *nbr;
69310a67 2057
718e3744 2058 /* increment statistics. */
2059 oi->ls_ack_in++;
2060
d3f0d621 2061 nbr = ospf_nbr_lookup (oi, iph, ospfh);
718e3744 2062 if (nbr == NULL)
2063 {
2064 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2065 inet_ntoa (ospfh->router_id));
2066 return;
2067 }
2068
57c5c652
PJ
2069 /* Add event to thread. */
2070 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2071
718e3744 2072 if (nbr->state < NSM_Exchange)
2073 {
3aa8d5f9 2074 zlog_warn ("Link State Acknowledgment: "
2075 "Neighbor[%s] state %s is less than Exchange",
2076 inet_ntoa (ospfh->router_id),
2077 LOOKUP(ospf_nsm_state_msg, nbr->state));
718e3744 2078 return;
2079 }
69310a67 2080
718e3744 2081 while (size >= OSPF_LSA_HEADER_SIZE)
2082 {
2083 struct ospf_lsa *lsa, *lsr;
2084
2085 lsa = ospf_lsa_new ();
2086 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2087
2088 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2089 size -= OSPF_LSA_HEADER_SIZE;
9985f83c 2090 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
718e3744 2091
2092 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2093 {
2094 lsa->data = NULL;
2095 ospf_lsa_discard (lsa);
2096 continue;
2097 }
2098
2099 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2100
2101 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2102 {
2103#ifdef HAVE_OPAQUE_LSA
718e3744 2104 if (IS_OPAQUE_LSA (lsr->data->type))
69310a67 2105 ospf_opaque_ls_ack_received (nbr, lsr);
718e3744 2106#endif /* HAVE_OPAQUE_LSA */
2107
2108 ospf_ls_retransmit_delete (nbr, lsr);
2109 }
2110
2111 lsa->data = NULL;
2112 ospf_lsa_discard (lsa);
2113 }
2114
718e3744 2115 return;
718e3744 2116}
2117\f
038163fa 2118static struct stream *
5c33349b 2119ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
718e3744 2120{
2121 int ret;
5c33349b 2122 struct ip *iph;
718e3744 2123 u_int16_t ip_len;
718e3744 2124 unsigned int ifindex = 0;
2125 struct iovec iov;
d0deca68 2126 /* Header and data both require alignment. */
e304982e 2127 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
2dd8bb4e 2128 struct msghdr msgh;
2129
68defd6d 2130 memset (&msgh, 0, sizeof (struct msghdr));
2dd8bb4e 2131 msgh.msg_iov = &iov;
2132 msgh.msg_iovlen = 1;
2133 msgh.msg_control = (caddr_t) buff;
2134 msgh.msg_controllen = sizeof (buff);
2dd8bb4e 2135
5c33349b 2136 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2137 if (ret < 0)
718e3744 2138 {
5c33349b 2139 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2140 return NULL;
2141 }
69310a67 2142 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
5c33349b 2143 {
2144 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2145 "(ip header size is %u)",
2146 ret, (u_int)sizeof(iph));
718e3744 2147 return NULL;
2148 }
18b12c38 2149
5c33349b 2150 /* Note that there should not be alignment problems with this assignment
2151 because this is at the beginning of the stream data buffer. */
2152 iph = (struct ip *) STREAM_DATA(ibuf);
2153 sockopt_iphdrincl_swab_systoh (iph);
18b12c38 2154
5c33349b 2155 ip_len = iph->ip_len;
6b333611 2156
de5ccb96 2157#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
718e3744 2158 /*
2159 * Kernel network code touches incoming IP header parameters,
2160 * before protocol specific processing.
2161 *
2162 * 1) Convert byteorder to host representation.
2163 * --> ip_len, ip_id, ip_off
2164 *
2165 * 2) Adjust ip_len to strip IP header size!
2166 * --> If user process receives entire IP packet via RAW
2167 * socket, it must consider adding IP header size to
2168 * the "ip_len" field of "ip" structure.
2169 *
2170 * For more details, see <netinet/ip_input.c>.
2171 */
5c33349b 2172 ip_len = ip_len + (iph->ip_hl << 2);
718e3744 2173#endif
2174
0150c9c9
DB
2175#if defined(__DragonFly__)
2176 /*
2177 * in DragonFly's raw socket, ip_len/ip_off are read
2178 * in network byte order.
2179 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2180 */
2181 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2182#endif
2183
863082d5 2184 ifindex = getsockopt_ifindex (AF_INET, &msgh);
718e3744 2185
2186 *ifp = if_lookup_by_index (ifindex);
2187
2188 if (ret != ip_len)
2189 {
5c33349b 2190 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2191 "but recvmsg returned %d", ip_len, ret);
718e3744 2192 return NULL;
2193 }
2194
2195 return ibuf;
2196}
2197
4dadc291 2198static struct ospf_interface *
d3f0d621 2199ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
718e3744 2200 struct ip *iph, struct ospf_header *ospfh)
2201{
2202 struct ospf_interface *rcv_oi;
718e3744 2203 struct ospf_vl_data *vl_data;
2204 struct ospf_area *vl_area;
52dc7ee6 2205 struct listnode *node;
718e3744 2206
2207 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2208 !OSPF_IS_AREA_BACKBONE (ospfh))
d3f0d621 2209 return NULL;
718e3744 2210
d3f0d621 2211 /* look for local OSPF interface matching the destination
2212 * to determine Area ID. We presume therefore the destination address
2213 * is unique, or at least (for "unnumbered" links), not used in other
2214 * areas
2215 */
2216 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2217 iph->ip_dst)) == NULL)
2218 return NULL;
718e3744 2219
1eb8ef25 2220 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
718e3744 2221 {
020709f9 2222 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
718e3744 2223 if (!vl_area)
2224 continue;
2225
2226 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2227 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2228 {
2229 if (IS_DEBUG_OSPF_EVENT)
2a42e285 2230 zlog_debug ("associating packet with %s",
718e3744 2231 IF_NAME (vl_data->vl_oi));
2232 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2233 {
2234 if (IS_DEBUG_OSPF_EVENT)
2a42e285 2235 zlog_debug ("This VL is not up yet, sorry");
718e3744 2236 return NULL;
2237 }
2238
2239 return vl_data->vl_oi;
2240 }
2241 }
2242
2243 if (IS_DEBUG_OSPF_EVENT)
2a42e285 2244 zlog_debug ("couldn't find any VL to associate the packet with");
718e3744 2245
d3f0d621 2246 return NULL;
718e3744 2247}
2248
f63f06da 2249static int
718e3744 2250ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2251{
2252 /* Check match the Area ID of the receiving interface. */
2253 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2254 return 1;
2255
2256 return 0;
2257}
2258
2259/* Unbound socket will accept any Raw IP packets if proto is matched.
2260 To prevent it, compare src IP address and i/f address with masking
2261 i/f network mask. */
4dadc291 2262static int
718e3744 2263ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2264{
2265 struct in_addr mask, me, him;
2266
2267 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2268 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2269 return 1;
2270
2271 masklen2ip (oi->address->prefixlen, &mask);
2272
2273 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2274 him.s_addr = ip_src.s_addr & mask.s_addr;
2275
2276 if (IPV4_ADDR_SAME (&me, &him))
2277 return 1;
2278
2279 return 0;
2280}
2281
bd5651f0
DO
2282/* Return 1, if the packet is properly authenticated and checksummed,
2283 0 otherwise. In particular, check that AuType header field is valid and
2284 matches the locally configured AuType, and that D.5 requirements are met. */
4dadc291 2285static int
e5259148 2286ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
718e3744 2287{
718e3744 2288 struct crypt_key *ck;
bd5651f0
DO
2289 u_int16_t iface_auth_type;
2290 u_int16_t pkt_auth_type = ntohs (ospfh->auth_type);
718e3744 2291
bd5651f0
DO
2292 switch (pkt_auth_type)
2293 {
2294 case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
2295 if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))
718e3744 2296 {
bd5651f0
DO
2297 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2298 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null",
2299 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2300 return 0;
718e3744 2301 }
bd5651f0
DO
2302 if (! ospf_check_sum (ospfh))
2303 {
2304 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2305 zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s",
2306 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2307 return 0;
2308 }
2309 return 1;
2310 case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */
2311 if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi)))
2312 {
2313 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2314 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple",
2315 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2316 return 0;
2317 }
2318 if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2319 {
2320 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2321 zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi));
2322 return 0;
2323 }
2324 if (! ospf_check_sum (ospfh))
2325 {
2326 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2327 zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s",
2328 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2329 return 0;
2330 }
2331 return 1;
2332 case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */
2333 if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi)))
2334 {
2335 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2336 zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2337 IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2338 return 0;
2339 }
2340 if (ospfh->checksum)
2341 {
2342 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2343 zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi));
2344 return 0;
2345 }
2346 /* only MD5 crypto method can pass ospf_packet_examin() */
2347 if
2348 (
2349 NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) ||
2350 ospfh->u.crypt.key_id != ck->key_id ||
2351 /* Condition above uses the last key ID on the list, which is
2352 different from what ospf_crypt_key_lookup() does. A bug? */
2353 ! ospf_check_md5_digest (oi, ospfh)
2354 )
2355 {
2356 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2357 zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi));
2358 return 0;
2359 }
2360 return 1;
2361 default:
2362 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2363 zlog_warn ("interface %s: invalid packet auth-type (%02x)",
2364 IF_NAME (oi), pkt_auth_type);
2365 return 0;
2366 }
718e3744 2367}
2368
4dadc291 2369static int
718e3744 2370ospf_check_sum (struct ospf_header *ospfh)
2371{
2372 u_int32_t ret;
2373 u_int16_t sum;
718e3744 2374
2375 /* clear auth_data for checksum. */
2376 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2377
2378 /* keep checksum and clear. */
2379 sum = ospfh->checksum;
2380 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2381
2382 /* calculate checksum. */
2383 ret = in_cksum (ospfh, ntohs (ospfh->length));
2384
2385 if (ret != sum)
2386 {
2387 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2388 ret, sum);
2389 return 0;
2390 }
2391
2392 return 1;
2393}
2394
4e31de79
DO
2395/* Verify, that given link/TOS records are properly sized/aligned and match
2396 Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2397static unsigned
2398ospf_router_lsa_links_examin
2399(
2400 struct router_lsa_link * link,
2401 u_int16_t linkbytes,
2402 const u_int16_t num_links
2403)
2404{
2405 unsigned counted_links = 0, thislinklen;
2406
2407 while (linkbytes)
2408 {
2409 thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
2410 if (thislinklen > linkbytes)
2411 {
2412 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2413 zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
2414 return MSG_NG;
2415 }
2416 link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
2417 linkbytes -= thislinklen;
2418 counted_links++;
2419 }
2420 if (counted_links != num_links)
2421 {
2422 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2423 zlog_debug ("%s: %u link blocks declared, %u present",
2424 __func__, num_links, counted_links);
2425 return MSG_NG;
2426 }
2427 return MSG_OK;
2428}
2429
2430/* Verify, that the given LSA is properly sized/aligned (including type-specific
2431 minimum length constraint). */
2432static unsigned
2433ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
2434{
2435 unsigned ret;
2436 struct router_lsa * rlsa;
2437 if
2438 (
2439 lsah->type < OSPF_MAX_LSA &&
2440 ospf_lsa_minlen[lsah->type] &&
2441 lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
2442 )
2443 {
2444 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2445 zlog_debug ("%s: undersized (%u B) %s",
2446 __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
2447 return MSG_NG;
2448 }
2449 switch (lsah->type)
2450 {
2451 case OSPF_ROUTER_LSA:
2452 /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
2453 if (headeronly)
2454 {
2455 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2456 break;
2457 }
2458 rlsa = (struct router_lsa *) lsah;
2459 ret = ospf_router_lsa_links_examin
2460 (
2461 (struct router_lsa_link *) rlsa->link,
2462 lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
2463 ntohs (rlsa->links) /* 16 bits */
2464 );
2465 break;
2466 case OSPF_AS_EXTERNAL_LSA:
2467 /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
2468 case OSPF_AS_NSSA_LSA:
2469 /* RFC3101 C, idem */
2470 ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
2471 break;
2472 /* Following LSA types are considered OK length-wise as soon as their minimum
2473 * length constraint is met and length of the whole LSA is a multiple of 4
2474 * (basic LSA header size is already a multiple of 4). */
2475 case OSPF_NETWORK_LSA:
2476 /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2477 case OSPF_SUMMARY_LSA:
2478 case OSPF_ASBR_SUMMARY_LSA:
2479 /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
2480#ifdef HAVE_OPAQUE_LSA
2481 case OSPF_OPAQUE_LINK_LSA:
2482 case OSPF_OPAQUE_AREA_LSA:
2483 case OSPF_OPAQUE_AS_LSA:
2484 /* RFC5250 A.2, "some number of octets (of application-specific
2485 * data) padded to 32-bit alignment." This is considered equivalent
2486 * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
2487 * file for the detailed analysis of this passage. */
2488#endif
2489 ret = lsalen % 4 ? MSG_NG : MSG_OK;
2490 break;
2491 default:
2492 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2493 zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
2494 return MSG_NG;
2495 }
2496 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2497 zlog_debug ("%s: alignment error in %s",
2498 __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
2499 return ret;
2500}
2501
2502/* Verify if the provided input buffer is a valid sequence of LSAs. This
2503 includes verification of LSA blocks length/alignment and dispatching
2504 of deeper-level checks. */
2505static unsigned
2506ospf_lsaseq_examin
2507(
2508 struct lsa_header *lsah, /* start of buffered data */
2509 size_t length,
2510 const u_char headeronly,
2511 /* When declared_num_lsas is not 0, compare it to the real number of LSAs
2512 and treat the difference as an error. */
2513 const u_int32_t declared_num_lsas
2514)
2515{
2516 u_int32_t counted_lsas = 0;
2517
2518 while (length)
2519 {
2520 u_int16_t lsalen;
2521 if (length < OSPF_LSA_HEADER_SIZE)
2522 {
2523 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2524 zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
2525 __func__, length, counted_lsas);
2526 return MSG_NG;
2527 }
2528 /* save on ntohs() calls here and in the LSA validator */
2529 lsalen = ntohs (lsah->length);
2530 if (lsalen < OSPF_LSA_HEADER_SIZE)
2531 {
2532 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2533 zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
2534 __func__, counted_lsas, lsalen);
2535 return MSG_NG;
2536 }
2537 if (headeronly)
2538 {
2539 /* less checks here and in ospf_lsa_examin() */
2540 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
2541 {
2542 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2543 zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
2544 return MSG_NG;
2545 }
2546 lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
2547 length -= OSPF_LSA_HEADER_SIZE;
2548 }
2549 else
2550 {
2551 /* make sure the input buffer is deep enough before further checks */
2552 if (lsalen > length)
2553 {
2554 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2555 zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2556 __func__, counted_lsas, lsalen, length);
2557 return MSG_NG;
2558 }
2559 if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
2560 {
2561 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2562 zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
2563 return MSG_NG;
2564 }
2565 lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
2566 length -= lsalen;
2567 }
2568 counted_lsas++;
2569 }
2570
2571 if (declared_num_lsas && counted_lsas != declared_num_lsas)
2572 {
2573 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2574 zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
2575 __func__, declared_num_lsas, counted_lsas);
2576 return MSG_NG;
2577 }
2578 return MSG_OK;
2579}
2580
75c8eabb
DO
2581/* Verify a complete OSPF packet for proper sizing/alignment. */
2582static unsigned
2583ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2584{
bd5651f0 2585 u_int16_t bytesdeclared, bytesauth;
4e31de79
DO
2586 unsigned ret;
2587 struct ospf_ls_update * lsupd;
75c8eabb
DO
2588
2589 /* Length, 1st approximation. */
2590 if (bytesonwire < OSPF_HEADER_SIZE)
2591 {
2592 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2593 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2594 return MSG_NG;
2595 }
2596 /* Now it is safe to access header fields. Performing length check, allow
2597 * for possible extra bytes of crypto auth/padding, which are not counted
2598 * in the OSPF header "length" field. */
aee56745
DO
2599 if (oh->version != OSPF_VERSION)
2600 {
2601 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2602 zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
2603 return MSG_NG;
2604 }
75c8eabb 2605 bytesdeclared = ntohs (oh->length);
bd5651f0
DO
2606 if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2607 bytesauth = 0;
2608 else
2609 {
2610 if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE)
2611 {
2612 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2613 zlog_debug ("%s: unsupported crypto auth length (%u B)",
2614 __func__, oh->u.crypt.auth_data_len);
2615 return MSG_NG;
2616 }
2617 bytesauth = OSPF_AUTH_MD5_SIZE;
2618 }
2619 if (bytesdeclared + bytesauth > bytesonwire)
75c8eabb
DO
2620 {
2621 if (IS_DEBUG_OSPF_PACKET (0, RECV))
bd5651f0
DO
2622 zlog_debug ("%s: packet length error (%u real, %u+%u declared)",
2623 __func__, bytesonwire, bytesdeclared, bytesauth);
75c8eabb
DO
2624 return MSG_NG;
2625 }
2626 /* Length, 2nd approximation. The type-specific constraint is checked
2627 against declared length, not amount of bytes on wire. */
2628 if
2629 (
2630 oh->type >= OSPF_MSG_HELLO &&
2631 oh->type <= OSPF_MSG_LS_ACK &&
2632 bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2633 )
2634 {
2635 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2636 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2637 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2638 return MSG_NG;
2639 }
4e31de79
DO
2640 switch (oh->type)
2641 {
2642 case OSPF_MSG_HELLO:
2643 /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
2644 by N>=0 router-IDs. */
b29adf9c 2645 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
4e31de79
DO
2646 break;
2647 case OSPF_MSG_DB_DESC:
2648 /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
2649 by N>=0 header-only LSAs. */
2650 ret = ospf_lsaseq_examin
2651 (
2652 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
b29adf9c 2653 bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
4e31de79
DO
2654 1, /* header-only LSAs */
2655 0
2656 );
2657 break;
2658 case OSPF_MSG_LS_REQ:
2659 /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
b29adf9c 2660 ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
4e31de79
DO
2661 OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
2662 break;
2663 case OSPF_MSG_LS_UPD:
2664 /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
2665 by N>=0 full LSAs (with N declared beforehand). */
2666 lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
2667 ret = ospf_lsaseq_examin
2668 (
2669 (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
b29adf9c 2670 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
4e31de79
DO
2671 0, /* full LSAs */
2672 ntohl (lsupd->num_lsas) /* 32 bits */
2673 );
2674 break;
2675 case OSPF_MSG_LS_ACK:
2676 /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
2677 ret = ospf_lsaseq_examin
2678 (
2679 (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
b29adf9c 2680 bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
4e31de79
DO
2681 1, /* header-only LSAs */
2682 0
2683 );
2684 break;
2685 default:
2686 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2687 zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
2688 return MSG_NG;
2689 }
2690 if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2691 zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
2692 return ret;
75c8eabb
DO
2693}
2694
718e3744 2695/* OSPF Header verification. */
4dadc291 2696static int
718e3744 2697ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2698 struct ip *iph, struct ospf_header *ospfh)
2699{
718e3744 2700 /* Check Area ID. */
2701 if (!ospf_check_area_id (oi, ospfh))
2702 {
2703 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2704 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2705 return -1;
2706 }
2707
2708 /* Check network mask, Silently discarded. */
2709 if (! ospf_check_network_mask (oi, iph->ip_src))
2710 {
2711 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2712 IF_NAME (oi), inet_ntoa (iph->ip_src));
2713 return -1;
2714 }
2715
bd5651f0 2716 /* Check authentication. The function handles logging actions, where required. */
e5259148 2717 if (! ospf_check_auth (oi, ospfh))
bd5651f0 2718 return -1;
718e3744 2719
2720 return 0;
2721}
2722
2723/* Starting point of packet process function. */
2724int
2725ospf_read (struct thread *thread)
2726{
2727 int ret;
2728 struct stream *ibuf;
68980084 2729 struct ospf *ospf;
718e3744 2730 struct ospf_interface *oi;
2731 struct ip *iph;
2732 struct ospf_header *ospfh;
2733 u_int16_t length;
2734 struct interface *ifp;
2735
2736 /* first of all get interface pointer. */
68980084 2737 ospf = THREAD_ARG (thread);
038163fa 2738
2739 /* prepare for next packet. */
2740 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
718e3744 2741
5c33349b 2742 stream_reset(ospf->ibuf);
2743 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
718e3744 2744 return -1;
75c8eabb 2745 /* This raw packet is known to be at least as big as its IP header. */
718e3744 2746
5c33349b 2747 /* Note that there should not be alignment problems with this assignment
2748 because this is at the beginning of the stream data buffer. */
06f953f7 2749 iph = (struct ip *) STREAM_DATA (ibuf);
5c33349b 2750 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
06f953f7 2751
ac191232 2752 if (ifp == NULL)
b87f772a 2753 /* Handle cases where the platform does not support retrieving the ifindex,
2754 and also platforms (such as Solaris 8) that claim to support ifindex
2755 retrieval but do not. */
ac191232 2756 ifp = if_lookup_address (iph->ip_src);
ac191232 2757
d3f0d621 2758 if (ifp == NULL)
5c33349b 2759 return 0;
718e3744 2760
2761 /* IP Header dump. */
17b78d38 2762 if (IS_DEBUG_OSPF_PACKET(0, RECV))
6b333611 2763 ospf_ip_header_dump (iph);
7d95c611 2764
718e3744 2765 /* Self-originated packet should be discarded silently. */
68980084 2766 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
718e3744 2767 {
d324181c 2768 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2769 {
2a42e285 2770 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
d324181c 2771 inet_ntoa (iph->ip_src));
2772 }
718e3744 2773 return 0;
2774 }
2775
61ab0301
DO
2776 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2777 by ospf_recv_packet() to be correct). */
9985f83c 2778 stream_forward_getp (ibuf, iph->ip_hl * 4);
61ab0301 2779
75c8eabb
DO
2780 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2781 if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
61ab0301 2782 return -1;
61ab0301 2783 /* Now it is safe to access all fields of OSPF packet header. */
718e3744 2784
2785 /* associate packet with ospf interface */
05cf46ba 2786 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
d3f0d621 2787
3aad46bd
YS
2788 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2789 after the passive/backbone/other checks below are passed. These checks
2790 in turn access the fields of unverified "ospfh" structure for their own
2791 purposes and must remain very accurate in doing this. */
71775043 2792
491eddc2
JT
2793 /* If incoming interface is passive one, ignore it. */
2794 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2795 {
2796 char buf[3][INET_ADDRSTRLEN];
2797
2798 if (IS_DEBUG_OSPF_EVENT)
2799 zlog_debug ("ignoring packet from router %s sent to %s, "
2800 "received on a passive interface, %s",
2801 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2802 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2803 inet_ntop(AF_INET, &oi->address->u.prefix4,
2804 buf[2], sizeof(buf[2])));
2805
2806 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2807 {
2808 /* Try to fix multicast membership.
2809 * Some OS:es may have problems in this area,
2810 * make sure it is removed.
2811 */
2812 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2813 ospf_if_set_multicast(oi);
2814 }
2815 return 0;
2816 }
2817
2818
d3f0d621 2819 /* if no local ospf_interface,
2820 * or header area is backbone but ospf_interface is not
2821 * check for VLINK interface
2822 */
2823 if ( (oi == NULL) ||
2824 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2825 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2826 )
718e3744 2827 {
d3f0d621 2828 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
d324181c 2829 {
88871b1d
PJ
2830 if (IS_DEBUG_OSPF_EVENT)
2831 zlog_debug ("Packet from [%s] received on link %s"
2832 " but no ospf_interface",
2833 inet_ntoa (iph->ip_src), ifp->name);
d3f0d621 2834 return 0;
d324181c 2835 }
d3f0d621 2836 }
05cf46ba 2837
d3f0d621 2838 /* else it must be a local ospf interface, check it was received on
2839 * correct link
2840 */
2841 else if (oi->ifp != ifp)
2842 {
11637435
PJ
2843 if (IS_DEBUG_OSPF_EVENT)
2844 zlog_warn ("Packet from [%s] received on wrong link %s",
2845 inet_ntoa (iph->ip_src), ifp->name);
718e3744 2846 return 0;
2847 }
847947f2 2848 else if (oi->state == ISM_Down)
c3eab871 2849 {
ba6454ec 2850 char buf[2][INET_ADDRSTRLEN];
2851 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
847947f2 2852 "down [%s]; interface flags are %s",
ba6454ec 2853 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2854 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2855 ifp->name, if_flag_dump(ifp->flags));
ba6454ec 2856 /* Fix multicast memberships? */
2857 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
429ac78c 2858 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ba6454ec 2859 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
429ac78c 2860 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ba6454ec 2861 if (oi->multicast_memberships)
2862 ospf_if_set_multicast(oi);
c3eab871 2863 return 0;
2864 }
718e3744 2865
2866 /*
2867 * If the received packet is destined for AllDRouters, the packet
2868 * should be accepted only if the received ospf interface state is
2869 * either DR or Backup -- endo.
2870 */
2871 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2872 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2873 {
ba6454ec 2874 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
718e3744 2875 inet_ntoa (iph->ip_src), IF_NAME (oi),
2876 LOOKUP (ospf_ism_state_msg, oi->state));
ba6454ec 2877 /* Try to fix multicast membership. */
2878 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2879 ospf_if_set_multicast(oi);
718e3744 2880 return 0;
2881 }
2882
3aad46bd
YS
2883 /* Verify more OSPF header fields. */
2884 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2885 if (ret < 0)
2886 {
2887 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2888 zlog_debug ("ospf_read[%s]: Header check failed, "
2889 "dropping.",
2890 inet_ntoa (iph->ip_src));
2891 return ret;
2892 }
2893
718e3744 2894 /* Show debug receiving packet. */
1aa7b399 2895 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2896 {
718e3744 2897 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
1aa7b399 2898 {
2a42e285 2899 zlog_debug ("-----------------------------------------------------");
1aa7b399 2900 ospf_packet_dump (ibuf);
2901 }
718e3744 2902
2a42e285 2903 zlog_debug ("%s received from [%s] via [%s]",
272ca1e3 2904 LOOKUP (ospf_packet_type_str, ospfh->type),
1aa7b399 2905 inet_ntoa (ospfh->router_id), IF_NAME (oi));
2a42e285 2906 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2907 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
718e3744 2908
2909 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2a42e285 2910 zlog_debug ("-----------------------------------------------------");
1aa7b399 2911 }
718e3744 2912
9985f83c 2913 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
718e3744 2914
2915 /* Adjust size to message length. */
2916 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2917
2918 /* Read rest of the packet and call each sort of packet routine. */
2919 switch (ospfh->type)
2920 {
2921 case OSPF_MSG_HELLO:
2922 ospf_hello (iph, ospfh, ibuf, oi, length);
2923 break;
2924 case OSPF_MSG_DB_DESC:
2925 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2926 break;
2927 case OSPF_MSG_LS_REQ:
2928 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2929 break;
2930 case OSPF_MSG_LS_UPD:
2931 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2932 break;
2933 case OSPF_MSG_LS_ACK:
2934 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2935 break;
2936 default:
2937 zlog (NULL, LOG_WARNING,
2938 "interface %s: OSPF packet header type %d is illegal",
2939 IF_NAME (oi), ospfh->type);
2940 break;
2941 }
2942
718e3744 2943 return 0;
2944}
2945
2946/* Make OSPF header. */
4dadc291 2947static void
718e3744 2948ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2949{
2950 struct ospf_header *ospfh;
2951
2952 ospfh = (struct ospf_header *) STREAM_DATA (s);
2953
2954 ospfh->version = (u_char) OSPF_VERSION;
2955 ospfh->type = (u_char) type;
2956
68980084 2957 ospfh->router_id = oi->ospf->router_id;
718e3744 2958
2959 ospfh->checksum = 0;
2960 ospfh->area_id = oi->area->area_id;
2961 ospfh->auth_type = htons (ospf_auth_type (oi));
2962
2963 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2964
9985f83c 2965 stream_forward_endp (s, OSPF_HEADER_SIZE);
718e3744 2966}
2967
2968/* Make Authentication Data. */
4dadc291 2969static int
718e3744 2970ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2971{
2972 struct crypt_key *ck;
2973
2974 switch (ospf_auth_type (oi))
2975 {
2976 case OSPF_AUTH_NULL:
2977 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2978 break;
2979 case OSPF_AUTH_SIMPLE:
2980 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2981 OSPF_AUTH_SIMPLE_SIZE);
2982 break;
2983 case OSPF_AUTH_CRYPTOGRAPHIC:
2984 /* If key is not set, then set 0. */
2985 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2986 {
2987 ospfh->u.crypt.zero = 0;
2988 ospfh->u.crypt.key_id = 0;
2989 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2990 }
2991 else
2992 {
1eb8ef25 2993 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
718e3744 2994 ospfh->u.crypt.zero = 0;
2995 ospfh->u.crypt.key_id = ck->key_id;
2996 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2997 }
2998 /* note: the seq is done in ospf_make_md5_digest() */
2999 break;
3000 default:
3001 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
3002 break;
3003 }
3004
3005 return 0;
3006}
3007
3008/* Fill rest of OSPF header. */
4dadc291 3009static void
718e3744 3010ospf_fill_header (struct ospf_interface *oi,
3011 struct stream *s, u_int16_t length)
3012{
3013 struct ospf_header *ospfh;
3014
3015 ospfh = (struct ospf_header *) STREAM_DATA (s);
3016
3017 /* Fill length. */
3018 ospfh->length = htons (length);
3019
3020 /* Calculate checksum. */
3021 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
3022 ospfh->checksum = in_cksum (ospfh, length);
3023 else
3024 ospfh->checksum = 0;
3025
3026 /* Add Authentication Data. */
3027 ospf_make_auth (oi, ospfh);
3028}
3029
4dadc291 3030static int
718e3744 3031ospf_make_hello (struct ospf_interface *oi, struct stream *s)
3032{
3033 struct ospf_neighbor *nbr;
3034 struct route_node *rn;
3035 u_int16_t length = OSPF_HELLO_MIN_SIZE;
3036 struct in_addr mask;
3037 unsigned long p;
3038 int flag = 0;
3039
3040 /* Set netmask of interface. */
3041 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
3042 oi->type != OSPF_IFTYPE_VIRTUALLINK)
3043 masklen2ip (oi->address->prefixlen, &mask);
3044 else
3045 memset ((char *) &mask, 0, sizeof (struct in_addr));
3046 stream_put_ipv4 (s, mask.s_addr);
3047
3048 /* Set Hello Interval. */
f9ad937f 3049 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
3050 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
3051 else
3052 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
718e3744 3053
3054 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3055 zlog_debug ("make_hello: options: %x, int: %s",
718e3744 3056 OPTIONS(oi), IF_NAME (oi));
3057
3058 /* Set Options. */
3059 stream_putc (s, OPTIONS (oi));
3060
3061 /* Set Router Priority. */
3062 stream_putc (s, PRIORITY (oi));
3063
3064 /* Set Router Dead Interval. */
3065 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
3066
3067 /* Set Designated Router. */
3068 stream_put_ipv4 (s, DR (oi).s_addr);
3069
9985f83c 3070 p = stream_get_endp (s);
718e3744 3071
3072 /* Set Backup Designated Router. */
3073 stream_put_ipv4 (s, BDR (oi).s_addr);
3074
3075 /* Add neighbor seen. */
3076 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
68980084 3077 if ((nbr = rn->info))
3078 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
3079 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
3080 if (nbr->state != NSM_Down) /* This is myself for DR election. */
3081 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
718e3744 3082 {
3083 /* Check neighbor is sane? */
68980084 3084 if (nbr->d_router.s_addr != 0
3085 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
3086 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
3087 flag = 1;
718e3744 3088
3089 stream_put_ipv4 (s, nbr->router_id.s_addr);
3090 length += 4;
3091 }
3092
3093 /* Let neighbor generate BackupSeen. */
3094 if (flag == 1)
3a9eb091 3095 stream_putl_at (s, p, 0); /* ipv4 address, normally */
718e3744 3096
3097 return length;
3098}
3099
4dadc291 3100static int
718e3744 3101ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
3102 struct stream *s)
3103{
3104 struct ospf_lsa *lsa;
3105 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
3106 u_char options;
3107 unsigned long pp;
3108 int i;
3109 struct ospf_lsdb *lsdb;
3110
3111 /* Set Interface MTU. */
3112 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3113 stream_putw (s, 0);
3114 else
3115 stream_putw (s, oi->ifp->mtu);
3116
3117 /* Set Options. */
3118 options = OPTIONS (oi);
3119#ifdef HAVE_OPAQUE_LSA
68980084 3120 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
718e3744 3121 {
3122 if (IS_SET_DD_I (nbr->dd_flags)
3123 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
3124 /*
3125 * Set O-bit in the outgoing DD packet for capablity negotiation,
3126 * if one of following case is applicable.
3127 *
3128 * 1) WaitTimer expiration event triggered the neighbor state to
3129 * change to Exstart, but no (valid) DD packet has received
3130 * from the neighbor yet.
3131 *
3132 * 2) At least one DD packet with O-bit on has received from the
3133 * neighbor.
3134 */
3135 SET_FLAG (options, OSPF_OPTION_O);
3136 }
3137#endif /* HAVE_OPAQUE_LSA */
3138 stream_putc (s, options);
3139
8dd24ee6 3140 /* DD flags */
9985f83c 3141 pp = stream_get_endp (s);
718e3744 3142 stream_putc (s, nbr->dd_flags);
3143
3144 /* Set DD Sequence Number. */
3145 stream_putl (s, nbr->dd_seqnum);
3146
b5aeb441 3147 /* shortcut unneeded walk of (empty) summary LSDBs */
718e3744 3148 if (ospf_db_summary_isempty (nbr))
b5aeb441 3149 goto empty;
718e3744 3150
3151 /* Describe LSA Header from Database Summary List. */
3152 lsdb = &nbr->db_sum;
3153
3154 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3155 {
3156 struct route_table *table = lsdb->type[i].db;
3157 struct route_node *rn;
3158
3159 for (rn = route_top (table); rn; rn = route_next (rn))
3160 if ((lsa = rn->info) != NULL)
3161 {
3162#ifdef HAVE_OPAQUE_LSA
3163 if (IS_OPAQUE_LSA (lsa->data->type)
3164 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
3165 {
3166 /* Suppress advertising opaque-informations. */
3167 /* Remove LSA from DB summary list. */
3168 ospf_lsdb_delete (lsdb, lsa);
3169 continue;
3170 }
3171#endif /* HAVE_OPAQUE_LSA */
3172
3173 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
3174 {
3175 struct lsa_header *lsah;
3176 u_int16_t ls_age;
3177
3178 /* DD packet overflows interface MTU. */
86f1fd96 3179 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
718e3744 3180 break;
3181
3182 /* Keep pointer to LS age. */
3183 lsah = (struct lsa_header *) (STREAM_DATA (s) +
9985f83c 3184 stream_get_endp (s));
718e3744 3185
3186 /* Proceed stream pointer. */
3187 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3188 length += OSPF_LSA_HEADER_SIZE;
3189
3190 /* Set LS age. */
3191 ls_age = LS_AGE (lsa);
3192 lsah->ls_age = htons (ls_age);
3193
3194 }
3195
3196 /* Remove LSA from DB summary list. */
3197 ospf_lsdb_delete (lsdb, lsa);
3198 }
3199 }
3200
8dd24ee6
PJ
3201 /* Update 'More' bit */
3202 if (ospf_db_summary_isempty (nbr))
3203 {
b5aeb441
PJ
3204empty:
3205 if (nbr->state >= NSM_Exchange)
3206 {
3207 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
3208 /* Rewrite DD flags */
3209 stream_putc_at (s, pp, nbr->dd_flags);
3210 }
3211 else
3212 {
3213 assert (IS_SET_DD_M(nbr->dd_flags));
3214 }
8dd24ee6 3215 }
718e3744 3216 return length;
3217}
3218
4dadc291 3219static int
718e3744 3220ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
3221 unsigned long delta, struct ospf_neighbor *nbr,
3222 struct ospf_lsa *lsa)
3223{
3224 struct ospf_interface *oi;
3225
3226 oi = nbr->oi;
3227
3228 /* LS Request packet overflows interface MTU. */
86f1fd96 3229 if (*length + delta > ospf_packet_max(oi))
718e3744 3230 return 0;
3231
3232 stream_putl (s, lsa->data->type);
3233 stream_put_ipv4 (s, lsa->data->id.s_addr);
3234 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
3235
1fe6ed38 3236 ospf_lsa_unlock (&nbr->ls_req_last);
718e3744 3237 nbr->ls_req_last = ospf_lsa_lock (lsa);
3238
3239 *length += 12;
3240 return 1;
3241}
3242
4dadc291 3243static int
718e3744 3244ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
3245{
3246 struct ospf_lsa *lsa;
3247 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
9985f83c 3248 unsigned long delta = stream_get_endp(s)+12;
718e3744 3249 struct route_table *table;
3250 struct route_node *rn;
3251 int i;
3252 struct ospf_lsdb *lsdb;
3253
3254 lsdb = &nbr->ls_req;
3255
3256 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3257 {
3258 table = lsdb->type[i].db;
3259 for (rn = route_top (table); rn; rn = route_next (rn))
3260 if ((lsa = (rn->info)) != NULL)
3261 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
3262 {
3263 route_unlock_node (rn);
3264 break;
3265 }
3266 }
3267 return length;
3268}
3269
4dadc291 3270static int
718e3744 3271ls_age_increment (struct ospf_lsa *lsa, int delay)
3272{
3273 int age;
3274
3275 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
3276
3277 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3278}
3279
4dadc291 3280static int
52dc7ee6 3281ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
718e3744 3282{
3283 struct ospf_lsa *lsa;
52dc7ee6 3284 struct listnode *node;
c9035ccd 3285 u_int16_t length = 0;
86f1fd96 3286 unsigned int size_noauth;
9985f83c 3287 unsigned long delta = stream_get_endp (s);
718e3744 3288 unsigned long pp;
3289 int count = 0;
3290
3291 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3292 zlog_debug ("ospf_make_ls_upd: Start");
59ea14c6 3293
9985f83c 3294 pp = stream_get_endp (s);
3295 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
c9035ccd 3296 length += OSPF_LS_UPD_MIN_SIZE;
718e3744 3297
86f1fd96 3298 /* Calculate amount of packet usable for data. */
3299 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3300
718e3744 3301 while ((node = listhead (update)) != NULL)
3302 {
3303 struct lsa_header *lsah;
3304 u_int16_t ls_age;
3305
3306 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3307 zlog_debug ("ospf_make_ls_upd: List Iteration");
718e3744 3308
1eb8ef25 3309 lsa = listgetdata (node);
3310
718e3744 3311 assert (lsa->data);
3312
68b7339a 3313 /* Will it fit? */
86f1fd96 3314 if (length + delta + ntohs (lsa->data->length) > size_noauth)
59ea14c6 3315 break;
3316
718e3744 3317 /* Keep pointer to LS age. */
9985f83c 3318 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
718e3744 3319
3320 /* Put LSA to Link State Request. */
3321 stream_put (s, lsa->data, ntohs (lsa->data->length));
3322
3323 /* Set LS age. */
3324 /* each hop must increment an lsa_age by transmit_delay
3325 of OSPF interface */
3326 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3327 lsah->ls_age = htons (ls_age);
3328
3329 length += ntohs (lsa->data->length);
3330 count++;
3331
3332 list_delete_node (update, node);
1fe6ed38 3333 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
718e3744 3334 }
3335
3336 /* Now set #LSAs. */
3a9eb091 3337 stream_putl_at (s, pp, count);
718e3744 3338
3339 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3340 zlog_debug ("ospf_make_ls_upd: Stop");
718e3744 3341 return length;
3342}
3343
4dadc291 3344static int
52dc7ee6 3345ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
718e3744 3346{
1fe6ed38 3347 struct listnode *node, *nnode;
718e3744 3348 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
9985f83c 3349 unsigned long delta = stream_get_endp(s) + 24;
718e3744 3350 struct ospf_lsa *lsa;
3351
1fe6ed38 3352 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
718e3744 3353 {
718e3744 3354 assert (lsa);
3355
86f1fd96 3356 if (length + delta > ospf_packet_max (oi))
718e3744 3357 break;
3358
3359 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3360 length += OSPF_LSA_HEADER_SIZE;
3361
718e3744 3362 listnode_delete (ack, lsa);
1fe6ed38 3363 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
718e3744 3364 }
3365
718e3744 3366 return length;
3367}
3368
aa276fd7
PJ
3369static void
3370ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
718e3744 3371{
3372 struct ospf_packet *op;
3373 u_int16_t length = OSPF_HEADER_SIZE;
3374
3375 op = ospf_packet_new (oi->ifp->mtu);
3376
3377 /* Prepare OSPF common header. */
3378 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3379
3380 /* Prepare OSPF Hello body. */
3381 length += ospf_make_hello (oi, op->s);
3382
3383 /* Fill OSPF header. */
3384 ospf_fill_header (oi, op->s, length);
3385
3386 /* Set packet length. */
3387 op->length = length;
3388
aa276fd7 3389 op->dst.s_addr = addr;
718e3744 3390
aa276fd7
PJ
3391 /* Add packet to the top of the interface output queue, so that they
3392 * can't get delayed by things like long queues of LS Update packets
3393 */
3394 ospf_packet_add_top (oi, op);
718e3744 3395
3396 /* Hook thread to write packet. */
020709f9 3397 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3398}
3399
4dadc291 3400static void
718e3744 3401ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3402{
3403 struct ospf_interface *oi;
3404
3405 oi = nbr_nbma->oi;
3406 assert(oi);
3407
3408 /* If this is passive interface, do not send OSPF Hello. */
7ffa8fa2 3409 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
718e3744 3410 return;
3411
3412 if (oi->type != OSPF_IFTYPE_NBMA)
3413 return;
3414
3415 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3416 return;
3417
3418 if (PRIORITY(oi) == 0)
3419 return;
3420
3421 if (nbr_nbma->priority == 0
3422 && oi->state != ISM_DR && oi->state != ISM_Backup)
3423 return;
3424
aa276fd7 3425 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
718e3744 3426}
3427
3428int
3429ospf_poll_timer (struct thread *thread)
3430{
3431 struct ospf_nbr_nbma *nbr_nbma;
3432
3433 nbr_nbma = THREAD_ARG (thread);
3434 nbr_nbma->t_poll = NULL;
3435
3436 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2a42e285 3437 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
718e3744 3438 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3439
3440 ospf_poll_send (nbr_nbma);
3441
3442 if (nbr_nbma->v_poll > 0)
3443 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3444 nbr_nbma->v_poll);
3445
3446 return 0;
3447}
3448
3449
3450int
3451ospf_hello_reply_timer (struct thread *thread)
3452{
3453 struct ospf_neighbor *nbr;
3454
3455 nbr = THREAD_ARG (thread);
3456 nbr->t_hello_reply = NULL;
3457
3458 assert (nbr->oi);
3459
3460 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2a42e285 3461 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
718e3744 3462 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3463
aa276fd7 3464 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
718e3744 3465
3466 return 0;
3467}
3468
3469/* Send OSPF Hello. */
3470void
3471ospf_hello_send (struct ospf_interface *oi)
3472{
718e3744 3473 /* If this is passive interface, do not send OSPF Hello. */
7ffa8fa2 3474 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
718e3744 3475 return;
3476
718e3744 3477 if (oi->type == OSPF_IFTYPE_NBMA)
3478 {
3479 struct ospf_neighbor *nbr;
3480 struct route_node *rn;
3481
3482 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3483 if ((nbr = rn->info))
3484 if (nbr != oi->nbr_self)
3485 if (nbr->state != NSM_Down)
3486 {
3487 /* RFC 2328 Section 9.5.1
3488 If the router is not eligible to become Designated Router,
3489 it must periodically send Hello Packets to both the
3490 Designated Router and the Backup Designated Router (if they
3491 exist). */
3492 if (PRIORITY(oi) == 0 &&
3493 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3494 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3495 continue;
3496
3497 /* If the router is eligible to become Designated Router, it
3498 must periodically send Hello Packets to all neighbors that
3499 are also eligible. In addition, if the router is itself the
3500 Designated Router or Backup Designated Router, it must also
3501 send periodic Hello Packets to all other neighbors. */
3502
3503 if (nbr->priority == 0 && oi->state == ISM_DROther)
3504 continue;
3505 /* if oi->state == Waiting, send hello to all neighbors */
aa276fd7 3506 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
718e3744 3507 }
718e3744 3508 }
3509 else
3510 {
3511 /* Decide destination address. */
3512 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
aa276fd7
PJ
3513 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3514 else
3515 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
718e3744 3516 }
3517}
3518
3519/* Send OSPF Database Description. */
3520void
3521ospf_db_desc_send (struct ospf_neighbor *nbr)
3522{
3523 struct ospf_interface *oi;
3524 struct ospf_packet *op;
3525 u_int16_t length = OSPF_HEADER_SIZE;
3526
3527 oi = nbr->oi;
3528 op = ospf_packet_new (oi->ifp->mtu);
3529
3530 /* Prepare OSPF common header. */
3531 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3532
3533 /* Prepare OSPF Database Description body. */
3534 length += ospf_make_db_desc (oi, nbr, op->s);
3535
3536 /* Fill OSPF header. */
3537 ospf_fill_header (oi, op->s, length);
3538
3539 /* Set packet length. */
3540 op->length = length;
3541
3542 /* Decide destination address. */
53d0dece
JT
3543 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3544 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3545 else
3546 op->dst = nbr->address.u.prefix4;
718e3744 3547
3548 /* Add packet to the interface output queue. */
3549 ospf_packet_add (oi, op);
3550
3551 /* Hook thread to write packet. */
020709f9 3552 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3553
3554 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3555 if (nbr->last_send)
3556 ospf_packet_free (nbr->last_send);
3557 nbr->last_send = ospf_packet_dup (op);
2518efd1 3558 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
718e3744 3559}
3560
3561/* Re-send Database Description. */
3562void
3563ospf_db_desc_resend (struct ospf_neighbor *nbr)
3564{
3565 struct ospf_interface *oi;
3566
3567 oi = nbr->oi;
3568
3569 /* Add packet to the interface output queue. */
3570 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3571
3572 /* Hook thread to write packet. */
020709f9 3573 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3574}
3575
3576/* Send Link State Request. */
3577void
3578ospf_ls_req_send (struct ospf_neighbor *nbr)
3579{
3580 struct ospf_interface *oi;
3581 struct ospf_packet *op;
3582 u_int16_t length = OSPF_HEADER_SIZE;
3583
3584 oi = nbr->oi;
3585 op = ospf_packet_new (oi->ifp->mtu);
3586
3587 /* Prepare OSPF common header. */
3588 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3589
3590 /* Prepare OSPF Link State Request body. */
3591 length += ospf_make_ls_req (nbr, op->s);
3592 if (length == OSPF_HEADER_SIZE)
3593 {
3594 ospf_packet_free (op);
3595 return;
3596 }
3597
3598 /* Fill OSPF header. */
3599 ospf_fill_header (oi, op->s, length);
3600
3601 /* Set packet length. */
3602 op->length = length;
3603
3604 /* Decide destination address. */
53d0dece
JT
3605 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3606 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3607 else
3608 op->dst = nbr->address.u.prefix4;
718e3744 3609
3610 /* Add packet to the interface output queue. */
3611 ospf_packet_add (oi, op);
3612
3613 /* Hook thread to write packet. */
020709f9 3614 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3615
3616 /* Add Link State Request Retransmission Timer. */
3617 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3618}
3619
3620/* Send Link State Update with an LSA. */
3621void
3622ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3623 int flag)
3624{
52dc7ee6 3625 struct list *update;
718e3744 3626
3627 update = list_new ();
3628
3629 listnode_add (update, lsa);
3630 ospf_ls_upd_send (nbr, update, flag);
3631
3632 list_delete (update);
3633}
3634
68b7339a 3635/* Determine size for packet. Must be at least big enough to accomodate next
3636 * LSA on list, which may be bigger than MTU size.
3637 *
3638 * Return pointer to new ospf_packet
3639 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3640 * on packet sizes (in which case offending LSA is deleted from update list)
3641 */
3642static struct ospf_packet *
3643ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3644{
3645 struct ospf_lsa *lsa;
3646 struct listnode *ln;
3647 size_t size;
3648 static char warned = 0;
3649
1eb8ef25 3650 lsa = listgetdata((ln = listhead (update)));
68b7339a 3651 assert (lsa->data);
3652
3653 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3654 > ospf_packet_max (oi))
3655 {
3656 if (!warned)
3657 {
3658 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3659 "will need to fragment. Not optimal. Try divide up"
3660 " your network with areas. Use 'debug ospf packet send'"
3661 " to see details, or look at 'show ip ospf database ..'");
3662 warned = 1;
3663 }
3664
3665 if (IS_DEBUG_OSPF_PACKET (0, SEND))
2a42e285 3666 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
68b7339a 3667 " %d bytes originated by %s, will be fragmented!",
3668 inet_ntoa (lsa->data->id),
3669 ntohs (lsa->data->length),
3670 inet_ntoa (lsa->data->adv_router));
3671
3672 /*
3673 * Allocate just enough to fit this LSA only, to avoid including other
3674 * LSAs in fragmented LSA Updates.
3675 */
3676 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3677 + OSPF_LS_UPD_MIN_SIZE;
3678 }
3679 else
3680 size = oi->ifp->mtu;
3681
3682 if (size > OSPF_MAX_PACKET_SIZE)
3683 {
3684 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
64511f39 3685 " %d bytes, packet size %ld, dropping it completely."
68b7339a 3686 " OSPF routing is broken!",
37ccfa3d 3687 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
62d8e96a 3688 (long int) size);
68b7339a 3689 list_delete_node (update, ln);
3690 return NULL;
3691 }
3692
c9035ccd
DT
3693 /* IP header is built up separately by ospf_write(). This means, that we must
3694 * reduce the "affordable" size just calculated by length of an IP header.
3695 * This makes sure, that even if we manage to fill the payload with LSA data
3696 * completely, the final packet (our data plus IP header) still fits into
3697 * outgoing interface MTU. This correction isn't really meaningful for an
3698 * oversized LSA, but for consistency the correction is done for both cases.
3699 *
3700 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3701 */
3702 return ospf_packet_new (size - sizeof (struct ip));
68b7339a 3703}
3704
718e3744 3705static void
52dc7ee6 3706ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
718e3744 3707 struct in_addr addr)
3708{
3709 struct ospf_packet *op;
3710 u_int16_t length = OSPF_HEADER_SIZE;
3711
3712 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3713 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
68b7339a 3714
3715 op = ospf_ls_upd_packet_new (update, oi);
718e3744 3716
3717 /* Prepare OSPF common header. */
3718 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3719
59ea14c6 3720 /* Prepare OSPF Link State Update body.
3721 * Includes Type-7 translation.
3722 */
718e3744 3723 length += ospf_make_ls_upd (oi, update, op->s);
3724
3725 /* Fill OSPF header. */
3726 ospf_fill_header (oi, op->s, length);
3727
3728 /* Set packet length. */
3729 op->length = length;
3730
3731 /* Decide destination address. */
53d0dece
JT
3732 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3733 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3734 else
3735 op->dst.s_addr = addr.s_addr;
718e3744 3736
3737 /* Add packet to the interface output queue. */
3738 ospf_packet_add (oi, op);
3739
3740 /* Hook thread to write packet. */
020709f9 3741 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3742}
3743
3744static int
3745ospf_ls_upd_send_queue_event (struct thread *thread)
3746{
3747 struct ospf_interface *oi = THREAD_ARG(thread);
3748 struct route_node *rn;
736d3441 3749 struct route_node *rnext;
59ea14c6 3750 struct list *update;
68b7339a 3751 char again = 0;
718e3744 3752
3753 oi->t_ls_upd_event = NULL;
3754
3755 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3756 zlog_debug ("ospf_ls_upd_send_queue start");
718e3744 3757
736d3441 3758 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
718e3744 3759 {
736d3441 3760 rnext = route_next (rn);
3761
718e3744 3762 if (rn->info == NULL)
736d3441 3763 continue;
68b7339a 3764
3765 update = (struct list *)rn->info;
718e3744 3766
48fe13bf 3767 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
718e3744 3768
68b7339a 3769 /* list might not be empty. */
59ea14c6 3770 if (listcount(update) == 0)
3771 {
3772 list_delete (rn->info);
3773 rn->info = NULL;
3774 route_unlock_node (rn);
3775 }
3776 else
68b7339a 3777 again = 1;
59ea14c6 3778 }
3779
3780 if (again != 0)
3781 {
3782 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3783 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
59ea14c6 3784 " %d nodes to try again, raising new event", again);
3785 oi->t_ls_upd_event =
3786 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
718e3744 3787 }
3788
3789 if (IS_DEBUG_OSPF_EVENT)
2a42e285 3790 zlog_debug ("ospf_ls_upd_send_queue stop");
59ea14c6 3791
718e3744 3792 return 0;
3793}
3794
3795void
52dc7ee6 3796ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
718e3744 3797{
3798 struct ospf_interface *oi;
1eb8ef25 3799 struct ospf_lsa *lsa;
718e3744 3800 struct prefix_ipv4 p;
3801 struct route_node *rn;
1eb8ef25 3802 struct listnode *node;
718e3744 3803
3804 oi = nbr->oi;
3805
3806 p.family = AF_INET;
3807 p.prefixlen = IPV4_MAX_BITLEN;
3808
3809 /* Decide destination address. */
3810 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3811 p.prefix = oi->vl_data->peer_addr;
53d0dece
JT
3812 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3813 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
718e3744 3814 else if (flag == OSPF_SEND_PACKET_DIRECT)
3815 p.prefix = nbr->address.u.prefix4;
3816 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3817 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
7afa08da 3818 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3819 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
718e3744 3820 else
3821 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3822
3823 if (oi->type == OSPF_IFTYPE_NBMA)
3824 {
3825 if (flag == OSPF_SEND_PACKET_INDIRECT)
3826 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3827 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3828 zlog_warn ("* LS-Update is sent to myself.");
3829 }
3830
3831 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3832
3833 if (rn->info == NULL)
3834 rn->info = list_new ();
3835
1eb8ef25 3836 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
1fe6ed38 3837 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
718e3744 3838
3839 if (oi->t_ls_upd_event == NULL)
3840 oi->t_ls_upd_event =
3841 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3842}
3843
3844static void
52dc7ee6 3845ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3846 struct in_addr dst)
718e3744 3847{
3848 struct ospf_packet *op;
3849 u_int16_t length = OSPF_HEADER_SIZE;
3850
3851 op = ospf_packet_new (oi->ifp->mtu);
3852
3853 /* Prepare OSPF common header. */
3854 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3855
3856 /* Prepare OSPF Link State Acknowledgment body. */
3857 length += ospf_make_ls_ack (oi, ack, op->s);
3858
3859 /* Fill OSPF header. */
3860 ospf_fill_header (oi, op->s, length);
3861
3862 /* Set packet length. */
3863 op->length = length;
3864
3865 /* Set destination IP address. */
3866 op->dst = dst;
3867
3868 /* Add packet to the interface output queue. */
3869 ospf_packet_add (oi, op);
3870
3871 /* Hook thread to write packet. */
020709f9 3872 OSPF_ISM_WRITE_ON (oi->ospf);
718e3744 3873}
3874
3875static int
3876ospf_ls_ack_send_event (struct thread *thread)
3877{
3878 struct ospf_interface *oi = THREAD_ARG (thread);
3879
3880 oi->t_ls_ack_direct = NULL;
3881
3882 while (listcount (oi->ls_ack_direct.ls_ack))
3883 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3884 oi->ls_ack_direct.dst);
3885
3886 return 0;
3887}
3888
3889void
3890ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3891{
3892 struct ospf_interface *oi = nbr->oi;
3893
3894 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3895 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3896
3897 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3898
3899 if (oi->t_ls_ack_direct == NULL)
3900 oi->t_ls_ack_direct =
3901 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3902}
3903
3904/* Send Link State Acknowledgment delayed. */
3905void
3906ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3907{
3908 struct in_addr dst;
3909
3910 /* Decide destination address. */
3911 /* RFC2328 Section 13.5 On non-broadcast
3912 networks, delayed Link State Acknowledgment packets must be
3913 unicast separately over each adjacency (i.e., neighbor whose
3914 state is >= Exchange). */
3915 if (oi->type == OSPF_IFTYPE_NBMA)
3916 {
3917 struct ospf_neighbor *nbr;
3918 struct route_node *rn;
3919
3920 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3921 if ((nbr = rn->info) != NULL)
3922 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3923 while (listcount (oi->ls_ack))
3924 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3925 return;
3926 }
3927 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3928 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3929 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3930 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3931 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3932 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
630e4807 3933 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3934 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
718e3744 3935 else
3936 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3937
3938 while (listcount (oi->ls_ack))
3939 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3940}