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