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