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