~ubuntu-branches/ubuntu/breezy/quagga/breezy-security

« back to all changes in this revision

Viewing changes to ospfd/ospf_packet.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-05-20 13:16:12 UTC
  • Revision ID: james.westby@ubuntu.com-20050520131612-pr6paalox60o3x3n
Tags: upstream-0.99.1
ImportĀ upstreamĀ versionĀ 0.99.1

Show diffs side-by-side

added added

removed removed

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