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