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