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