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

« back to all changes in this revision

Viewing changes to ospf6d/ospf6_message.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
 * Copyright (C) 2003 Yasuhiro Ohara
 
3
 *
 
4
 * This file is part of GNU Zebra.
 
5
 *
 
6
 * GNU Zebra is free software; you can redistribute it and/or modify it
 
7
 * under the terms of the GNU General Public License as published by the
 
8
 * Free Software Foundation; either version 2, or (at your option) any
 
9
 * later version.
 
10
 *
 
11
 * GNU Zebra is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with GNU Zebra; see the file COPYING.  If not, write to the 
 
18
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
 
19
 * Boston, MA 02111-1307, USA.  
 
20
 */
 
21
 
 
22
#include <zebra.h>
 
23
 
 
24
#include "memory.h"
 
25
#include "log.h"
 
26
#include "vty.h"
 
27
#include "command.h"
 
28
#include "thread.h"
 
29
#include "linklist.h"
 
30
 
 
31
#include "ospf6_proto.h"
 
32
#include "ospf6_lsa.h"
 
33
#include "ospf6_lsdb.h"
 
34
#include "ospf6_network.h"
 
35
#include "ospf6_message.h"
 
36
 
 
37
#include "ospf6_top.h"
 
38
#include "ospf6_area.h"
 
39
#include "ospf6_neighbor.h"
 
40
#include "ospf6_interface.h"
 
41
 
 
42
#include "ospf6_flood.h"
 
43
#include "ospf6d.h"
 
44
 
 
45
unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
 
46
const char *ospf6_message_type_str[] =
 
47
  { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" };
 
48
 
 
49
/* print functions */
 
50
 
 
51
static void
 
52
ospf6_header_print (struct ospf6_header *oh)
 
53
{
 
54
  char router_id[16], area_id[16];
 
55
  inet_ntop (AF_INET, &oh->router_id, router_id, sizeof (router_id));
 
56
  inet_ntop (AF_INET, &oh->area_id, area_id, sizeof (area_id));
 
57
 
 
58
  zlog_debug ("    OSPFv%d Type:%d Len:%hu Router-ID:%s",
 
59
             oh->version, oh->type, ntohs (oh->length), router_id);
 
60
  zlog_debug ("    Area-ID:%s Cksum:%hx Instance-ID:%d",
 
61
             area_id, ntohs (oh->checksum), oh->instance_id);
 
62
}
 
63
 
 
64
void
 
65
ospf6_hello_print (struct ospf6_header *oh)
 
66
{
 
67
  struct ospf6_hello *hello;
 
68
  char options[16];
 
69
  char drouter[16], bdrouter[16], neighbor[16];
 
70
  char *p;
 
71
 
 
72
  ospf6_header_print (oh);
 
73
  assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO);
 
74
 
 
75
  hello = (struct ospf6_hello *)
 
76
    ((caddr_t) oh + sizeof (struct ospf6_header));
 
77
 
 
78
  inet_ntop (AF_INET, &hello->drouter, drouter, sizeof (drouter));
 
79
  inet_ntop (AF_INET, &hello->bdrouter, bdrouter, sizeof (bdrouter));
 
80
  ospf6_options_printbuf (hello->options, options, sizeof (options));
 
81
 
 
82
  zlog_debug ("    I/F-Id:%ld Priority:%d Option:%s",
 
83
             (u_long) ntohl (hello->interface_id), hello->priority, options);
 
84
  zlog_debug ("    HelloInterval:%hu DeadInterval:%hu",
 
85
             ntohs (hello->hello_interval), ntohs (hello->dead_interval));
 
86
  zlog_debug ("    DR:%s BDR:%s", drouter, bdrouter);
 
87
 
 
88
  for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
 
89
       p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
 
90
       p += sizeof (u_int32_t))
 
91
    {
 
92
      inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor));
 
93
      zlog_debug ("    Neighbor: %s", neighbor);
 
94
    }
 
95
 
 
96
  if (p != OSPF6_MESSAGE_END (oh))
 
97
    zlog_debug ("Trailing garbage exists");
 
98
}
 
99
 
 
100
void
 
101
ospf6_dbdesc_print (struct ospf6_header *oh)
 
102
{
 
103
  struct ospf6_dbdesc *dbdesc;
 
104
  char options[16];
 
105
  char *p;
 
106
 
 
107
  ospf6_header_print (oh);
 
108
  assert (oh->type == OSPF6_MESSAGE_TYPE_DBDESC);
 
109
 
 
110
  dbdesc = (struct ospf6_dbdesc *)
 
111
    ((caddr_t) oh + sizeof (struct ospf6_header));
 
112
 
 
113
  ospf6_options_printbuf (dbdesc->options, options, sizeof (options));
 
114
 
 
115
  zlog_debug ("    MBZ: %#x Option: %s IfMTU: %hu",
 
116
             dbdesc->reserved1, options, ntohs (dbdesc->ifmtu));
 
117
  zlog_debug ("    MBZ: %#x Bits: %s%s%s SeqNum: %#lx",
 
118
             dbdesc->reserved2,
 
119
             (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"),
 
120
             (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"),
 
121
             (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"),
 
122
             (u_long) ntohl (dbdesc->seqnum));
 
123
 
 
124
  for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
 
125
       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
 
126
       p += sizeof (struct ospf6_lsa_header))
 
127
    ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
 
128
 
 
129
  if (p != OSPF6_MESSAGE_END (oh))
 
130
    zlog_debug ("Trailing garbage exists");
 
131
}
 
132
 
 
133
void
 
134
ospf6_lsreq_print (struct ospf6_header *oh)
 
135
{
 
136
  char id[16], adv_router[16];
 
137
  char *p;
 
138
 
 
139
  ospf6_header_print (oh);
 
140
  assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ);
 
141
 
 
142
  for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
 
143
       p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
 
144
       p += sizeof (struct ospf6_lsreq_entry))
 
145
    {
 
146
      struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *) p;
 
147
      inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router));
 
148
      inet_ntop (AF_INET, &e->id, id, sizeof (id));
 
149
      zlog_debug ("    [%s Id:%s Adv:%s]",
 
150
                 ospf6_lstype_name (e->type), id, adv_router);
 
151
    }
 
152
 
 
153
  if (p != OSPF6_MESSAGE_END (oh))
 
154
    zlog_debug ("Trailing garbage exists");
 
155
}
 
156
 
 
157
void
 
158
ospf6_lsupdate_print (struct ospf6_header *oh)
 
159
{
 
160
  struct ospf6_lsupdate *lsupdate;
 
161
  u_long num;
 
162
  char *p;
 
163
 
 
164
  ospf6_header_print (oh);
 
165
  assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE);
 
166
 
 
167
  lsupdate = (struct ospf6_lsupdate *)
 
168
    ((caddr_t) oh + sizeof (struct ospf6_header));
 
169
 
 
170
  num = ntohl (lsupdate->lsa_number);
 
171
  zlog_debug ("    Number of LSA: %ld", num);
 
172
 
 
173
  for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
 
174
       p < OSPF6_MESSAGE_END (oh) &&
 
175
       p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
 
176
       p += OSPF6_LSA_SIZE (p))
 
177
    {
 
178
      ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
 
179
      if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header))
 
180
        {
 
181
          zlog_debug ("    Malformed LSA length, quit printing");
 
182
          break;
 
183
        }
 
184
    }
 
185
 
 
186
  if (p != OSPF6_MESSAGE_END (oh))
 
187
    {
 
188
      char buf[32];
 
189
 
 
190
      int num = 0;
 
191
      memset (buf, 0, sizeof (buf));
 
192
 
 
193
      zlog_debug ("    Trailing garbage exists");
 
194
      while (p < OSPF6_MESSAGE_END (oh))
 
195
        {
 
196
          snprintf (buf, sizeof (buf), "%s %2x", buf, *p++);
 
197
          num++;
 
198
          if (num == 8)
 
199
            {
 
200
              zlog_debug ("    %s", buf);
 
201
              memset (buf, 0, sizeof (buf));
 
202
              num = 0;
 
203
            }
 
204
        }
 
205
      if (num)
 
206
        zlog_debug ("    %s", buf);
 
207
    }
 
208
}
 
209
 
 
210
void
 
211
ospf6_lsack_print (struct ospf6_header *oh)
 
212
{
 
213
  char *p;
 
214
 
 
215
  ospf6_header_print (oh);
 
216
  assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
 
217
 
 
218
  for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
 
219
       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
 
220
       p += sizeof (struct ospf6_lsa_header))
 
221
    ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
 
222
 
 
223
  if (p != OSPF6_MESSAGE_END (oh))
 
224
    zlog_debug ("Trailing garbage exists");
 
225
}
 
226
 
 
227
/* Receive function */
 
228
#define MSG_OK    0
 
229
#define MSG_NG    1
 
230
static int
 
231
ospf6_header_examin (struct in6_addr *src, struct in6_addr *dst,
 
232
                     struct ospf6_interface *oi, struct ospf6_header *oh)
 
233
{
 
234
  u_char type;
 
235
  type = OSPF6_MESSAGE_TYPE_CANONICAL (oh->type);
 
236
 
 
237
  /* version check */
 
238
  if (oh->version != OSPFV3_VERSION)
 
239
    {
 
240
      if (IS_OSPF6_DEBUG_MESSAGE (type, RECV))
 
241
        zlog_debug ("Message with unknown version");
 
242
      return MSG_NG;
 
243
    }
 
244
 
 
245
  /* Area-ID check */
 
246
  if (oh->area_id != oi->area->area_id)
 
247
    {
 
248
      if (oh->area_id == BACKBONE_AREA_ID)
 
249
        {
 
250
          if (IS_OSPF6_DEBUG_MESSAGE (type, RECV))
 
251
            zlog_debug ("Message may be via Virtual Link: not supported");
 
252
          return MSG_NG;
 
253
        }
 
254
 
 
255
      if (IS_OSPF6_DEBUG_MESSAGE (type, RECV))
 
256
        zlog_debug ("Area-ID mismatch");
 
257
      return MSG_NG;
 
258
    }
 
259
 
 
260
  /* Instance-ID check */
 
261
  if (oh->instance_id != oi->instance_id)
 
262
    {
 
263
      if (IS_OSPF6_DEBUG_MESSAGE (type, RECV))
 
264
        zlog_debug ("Instance-ID mismatch");
 
265
      return MSG_NG;
 
266
    }
 
267
 
 
268
  /* Router-ID check */
 
269
  if (oh->router_id == oi->area->ospf6->router_id)
 
270
    zlog_warn ("Detect duplicate Router-ID");
 
271
 
 
272
  return MSG_OK;
 
273
}
 
274
 
 
275
void
 
276
ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst,
 
277
                  struct ospf6_interface *oi, struct ospf6_header *oh)
 
278
{
 
279
  struct ospf6_hello *hello;
 
280
  struct ospf6_neighbor *on;
 
281
  char *p;
 
282
  int twoway = 0;
 
283
  int neighborchange = 0;
 
284
  int backupseen = 0;
 
285
 
 
286
  if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
 
287
    return;
 
288
 
 
289
  hello = (struct ospf6_hello *)
 
290
    ((caddr_t) oh + sizeof (struct ospf6_header));
 
291
 
 
292
  /* HelloInterval check */
 
293
  if (ntohs (hello->hello_interval) != oi->hello_interval)
 
294
    {
 
295
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
296
        zlog_debug ("HelloInterval mismatch");
 
297
      return;
 
298
    }
 
299
 
 
300
  /* RouterDeadInterval check */
 
301
  if (ntohs (hello->dead_interval) != oi->dead_interval)
 
302
    {
 
303
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
304
        zlog_debug ("RouterDeadInterval mismatch");
 
305
      return;
 
306
    }
 
307
 
 
308
  /* E-bit check */
 
309
  if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) !=
 
310
      OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E))
 
311
    {
 
312
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
313
        zlog_debug ("E-bit mismatch");
 
314
      return;
 
315
    }
 
316
 
 
317
  /* Find neighbor, create if not exist */
 
318
  on = ospf6_neighbor_lookup (oh->router_id, oi);
 
319
  if (on == NULL)
 
320
    {
 
321
      on = ospf6_neighbor_create (oh->router_id, oi);
 
322
      on->prev_drouter = on->drouter = hello->drouter;
 
323
      on->prev_bdrouter = on->bdrouter = hello->bdrouter;
 
324
      on->priority = hello->priority;
 
325
      on->ifindex = ntohl (hello->interface_id);
 
326
      memcpy (&on->linklocal_addr, src, sizeof (struct in6_addr));
 
327
    }
 
328
 
 
329
  /* TwoWay check */
 
330
  for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
 
331
       p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
 
332
       p += sizeof (u_int32_t))
 
333
    {
 
334
      u_int32_t *router_id = (u_int32_t *) p;
 
335
 
 
336
      if (*router_id == oi->area->ospf6->router_id)
 
337
        twoway++;
 
338
    }
 
339
 
 
340
  if (p != OSPF6_MESSAGE_END (oh))
 
341
    {
 
342
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
343
        zlog_debug ("Trailing garbage ignored");
 
344
    }
 
345
 
 
346
  /* RouterPriority check */
 
347
  if (on->priority != hello->priority)
 
348
    {
 
349
      on->priority = hello->priority;
 
350
      neighborchange++;
 
351
    }
 
352
 
 
353
  /* DR check */
 
354
  if (on->drouter != hello->drouter)
 
355
    {
 
356
      on->prev_drouter = on->drouter;
 
357
      on->drouter = hello->drouter;
 
358
      if (on->prev_drouter == on->router_id || on->drouter == on->router_id)
 
359
        neighborchange++;
 
360
    }
 
361
 
 
362
  /* BDR check */
 
363
  if (on->bdrouter != hello->bdrouter)
 
364
    {
 
365
      on->prev_bdrouter = on->bdrouter;
 
366
      on->bdrouter = hello->bdrouter;
 
367
      if (on->prev_bdrouter == on->router_id || on->bdrouter == on->router_id)
 
368
        neighborchange++;
 
369
    }
 
370
 
 
371
  /* BackupSeen check */
 
372
  if (oi->state == OSPF6_INTERFACE_WAITING)
 
373
    {
 
374
      if (hello->bdrouter == on->router_id)
 
375
        backupseen++;
 
376
      else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0))
 
377
        backupseen++;
 
378
    }
 
379
 
 
380
  /* Execute neighbor events */
 
381
  thread_execute (master, hello_received, on, 0);
 
382
  if (twoway)
 
383
    thread_execute (master, twoway_received, on, 0);
 
384
  else
 
385
    thread_execute (master, oneway_received, on, 0);
 
386
 
 
387
  /* Schedule interface events */
 
388
  if (backupseen)
 
389
    thread_add_event (master, backup_seen, oi, 0);
 
390
  if (neighborchange)
 
391
    thread_add_event (master, neighbor_change, oi, 0);
 
392
}
 
393
 
 
394
static void
 
395
ospf6_dbdesc_recv_master (struct ospf6_header *oh,
 
396
                          struct ospf6_neighbor *on)
 
397
{
 
398
  struct ospf6_dbdesc *dbdesc;
 
399
  char *p;
 
400
 
 
401
  dbdesc = (struct ospf6_dbdesc *)
 
402
    ((caddr_t) oh + sizeof (struct ospf6_header));
 
403
 
 
404
  if (on->state < OSPF6_NEIGHBOR_INIT)
 
405
    {
 
406
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
407
        zlog_debug ("Neighbor state less than Init, ignore");
 
408
      return;
 
409
    }
 
410
 
 
411
  switch (on->state)
 
412
    {
 
413
    case OSPF6_NEIGHBOR_TWOWAY:
 
414
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
415
        zlog_debug ("Neighbor state is 2-Way, ignore");
 
416
      return;
 
417
 
 
418
    case OSPF6_NEIGHBOR_INIT:
 
419
      thread_execute (master, twoway_received, on, 0);
 
420
      if (on->state != OSPF6_NEIGHBOR_EXSTART)
 
421
        {
 
422
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
423
            zlog_debug ("Neighbor state is not ExStart, ignore");
 
424
          return;
 
425
        }
 
426
      /* else fall through to ExStart */
 
427
 
 
428
    case OSPF6_NEIGHBOR_EXSTART:
 
429
      /* if neighbor obeys us as our slave, schedule negotiation_done
 
430
         and process LSA Headers. Otherwise, ignore this message */
 
431
      if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
 
432
          ! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
 
433
          ntohl (dbdesc->seqnum) == on->dbdesc_seqnum)
 
434
        {
 
435
          /* execute NegotiationDone */
 
436
          thread_execute (master, negotiation_done, on, 0);
 
437
 
 
438
          /* Record neighbor options */
 
439
          memcpy (on->options, dbdesc->options, sizeof (on->options));
 
440
        }
 
441
      else
 
442
        {
 
443
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
444
            zlog_debug ("Negotiation failed");
 
445
          return;
 
446
        }
 
447
      /* fall through to exchange */
 
448
 
 
449
    case OSPF6_NEIGHBOR_EXCHANGE:
 
450
      if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
 
451
        {
 
452
          /* Duplicated DatabaseDescription is dropped by master */
 
453
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
454
            zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
 
455
          return;
 
456
        }
 
457
 
 
458
      if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
 
459
        {
 
460
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
461
            zlog_debug ("Master/Slave bit mismatch");
 
462
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
463
          return;
 
464
        }
 
465
 
 
466
      if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
 
467
        {
 
468
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
469
            zlog_debug ("Initialize bit mismatch");
 
470
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
471
          return;
 
472
        }
 
473
 
 
474
      if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
 
475
        {
 
476
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
477
            zlog_debug ("Option field mismatch");
 
478
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
479
          return;
 
480
        }
 
481
 
 
482
      if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum)
 
483
        {
 
484
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
485
            zlog_debug ("Sequence number mismatch (%#lx expected)",
 
486
                       (u_long) on->dbdesc_seqnum);
 
487
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
488
          return;
 
489
        }
 
490
      break;
 
491
 
 
492
    case OSPF6_NEIGHBOR_LOADING:
 
493
    case OSPF6_NEIGHBOR_FULL:
 
494
      if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
 
495
        {
 
496
          /* Duplicated DatabaseDescription is dropped by master */
 
497
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
498
            zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
 
499
          return;
 
500
        }
 
501
 
 
502
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
503
        zlog_debug ("Not duplicate dbdesc in state %s",
 
504
                    ospf6_neighbor_state_str[on->state]);
 
505
      thread_add_event (master, seqnumber_mismatch, on, 0);
 
506
      return;
 
507
 
 
508
    default:
 
509
      assert (0);
 
510
      break;
 
511
    }
 
512
 
 
513
  /* Process LSA headers */
 
514
  for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
 
515
       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
 
516
       p += sizeof (struct ospf6_lsa_header))
 
517
    {
 
518
      struct ospf6_lsa *his, *mine;
 
519
      struct ospf6_lsdb *lsdb = NULL;
 
520
 
 
521
      his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
 
522
 
 
523
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
524
        zlog_debug ("%s", his->name);
 
525
 
 
526
      switch (OSPF6_LSA_SCOPE (his->header->type))
 
527
        {
 
528
        case OSPF6_SCOPE_LINKLOCAL:
 
529
          lsdb = on->ospf6_if->lsdb;
 
530
          break;
 
531
        case OSPF6_SCOPE_AREA:
 
532
          lsdb = on->ospf6_if->area->lsdb;
 
533
          break;
 
534
        case OSPF6_SCOPE_AS:
 
535
          lsdb = on->ospf6_if->area->ospf6->lsdb;
 
536
          break;
 
537
        case OSPF6_SCOPE_RESERVED:
 
538
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
539
            zlog_debug ("Ignoring LSA of reserved scope");
 
540
          ospf6_lsa_delete (his);
 
541
          continue;
 
542
          break;
 
543
        }
 
544
 
 
545
      if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
 
546
          IS_AREA_STUB (on->ospf6_if->area))
 
547
        {
 
548
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
549
            zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
 
550
          ospf6_lsa_delete (his);
 
551
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
552
          return;
 
553
        }
 
554
 
 
555
      mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
 
556
                                his->header->adv_router, lsdb);
 
557
      if (mine == NULL)
 
558
        {
 
559
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
560
            zlog_debug ("Add request (No database copy)");
 
561
          ospf6_lsdb_add (his, on->request_list);
 
562
        }
 
563
      else if (ospf6_lsa_compare (his, mine) < 0)
 
564
        {
 
565
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
566
            zlog_debug ("Add request (Received MoreRecent)");
 
567
          ospf6_lsdb_add (his, on->request_list);
 
568
        }
 
569
      else
 
570
        {
 
571
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
572
            zlog_debug ("Discard (Existing MoreRecent)");
 
573
          ospf6_lsa_delete (his);
 
574
        }
 
575
    }
 
576
 
 
577
  if (p != OSPF6_MESSAGE_END (oh))
 
578
    {
 
579
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
580
        zlog_debug ("Trailing garbage ignored");
 
581
    }
 
582
 
 
583
  /* Increment sequence number */
 
584
  on->dbdesc_seqnum ++;
 
585
 
 
586
  /* schedule send lsreq */
 
587
  if (on->thread_send_lsreq == NULL)
 
588
    on->thread_send_lsreq =
 
589
      thread_add_event (master, ospf6_lsreq_send, on, 0);
 
590
 
 
591
  THREAD_OFF (on->thread_send_dbdesc);
 
592
 
 
593
  /* More bit check */
 
594
  if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
 
595
      ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
 
596
    thread_add_event (master, exchange_done, on, 0);
 
597
  else
 
598
    on->thread_send_dbdesc =
 
599
      thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
 
600
 
 
601
  /* save last received dbdesc */
 
602
  memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
 
603
}
 
604
 
 
605
static void
 
606
ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
 
607
                         struct ospf6_neighbor *on)
 
608
{
 
609
  struct ospf6_dbdesc *dbdesc;
 
610
  char *p;
 
611
 
 
612
  dbdesc = (struct ospf6_dbdesc *)
 
613
    ((caddr_t) oh + sizeof (struct ospf6_header));
 
614
 
 
615
  if (on->state < OSPF6_NEIGHBOR_INIT)
 
616
    {
 
617
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
618
        zlog_debug ("Neighbor state less than Init, ignore");
 
619
      return;
 
620
    }
 
621
 
 
622
  switch (on->state)
 
623
    {
 
624
    case OSPF6_NEIGHBOR_TWOWAY:
 
625
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
626
        zlog_debug ("Neighbor state is 2-Way, ignore");
 
627
      return;
 
628
 
 
629
    case OSPF6_NEIGHBOR_INIT:
 
630
      thread_execute (master, twoway_received, on, 0);
 
631
      if (on->state != OSPF6_NEIGHBOR_EXSTART)
 
632
        {
 
633
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
634
            zlog_debug ("Neighbor state is not ExStart, ignore");
 
635
          return;
 
636
        }
 
637
      /* else fall through to ExStart */
 
638
 
 
639
    case OSPF6_NEIGHBOR_EXSTART:
 
640
      /* If the neighbor is Master, act as Slave. Schedule negotiation_done
 
641
         and process LSA Headers. Otherwise, ignore this message */
 
642
      if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
 
643
          CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
 
644
          CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
 
645
          ntohs (oh->length) == sizeof (struct ospf6_header) +
 
646
                                sizeof (struct ospf6_dbdesc))
 
647
        {
 
648
          /* set the master/slave bit to slave */
 
649
          UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
 
650
 
 
651
          /* set the DD sequence number to one specified by master */
 
652
          on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
 
653
 
 
654
          /* schedule NegotiationDone */
 
655
          thread_execute (master, negotiation_done, on, 0);
 
656
 
 
657
          /* Record neighbor options */
 
658
          memcpy (on->options, dbdesc->options, sizeof (on->options));
 
659
        }
 
660
      else
 
661
        {
 
662
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
663
            zlog_debug ("Negotiation failed");
 
664
          return;
 
665
        }
 
666
      break;
 
667
 
 
668
    case OSPF6_NEIGHBOR_EXCHANGE:
 
669
      if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
 
670
        {
 
671
          /* Duplicated DatabaseDescription causes slave to retransmit */
 
672
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
673
            zlog_debug ("Duplicated dbdesc causes retransmit");
 
674
          THREAD_OFF (on->thread_send_dbdesc);
 
675
          on->thread_send_dbdesc =
 
676
            thread_add_event (master, ospf6_dbdesc_send, on, 0);
 
677
          return;
 
678
        }
 
679
 
 
680
      if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
 
681
        {
 
682
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
683
            zlog_debug ("Master/Slave bit mismatch");
 
684
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
685
          return;
 
686
        }
 
687
 
 
688
      if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
 
689
        {
 
690
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
691
            zlog_debug ("Initialize bit mismatch");
 
692
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
693
          return;
 
694
        }
 
695
 
 
696
      if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
 
697
        {
 
698
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
699
            zlog_debug ("Option field mismatch");
 
700
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
701
          return;
 
702
        }
 
703
 
 
704
      if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum + 1)
 
705
        {
 
706
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
707
            zlog_debug ("Sequence number mismatch (%#lx expected)",
 
708
                        (u_long) on->dbdesc_seqnum + 1);
 
709
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
710
          return;
 
711
        }
 
712
      break;
 
713
 
 
714
    case OSPF6_NEIGHBOR_LOADING:
 
715
    case OSPF6_NEIGHBOR_FULL:
 
716
      if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
 
717
        {
 
718
          /* Duplicated DatabaseDescription causes slave to retransmit */
 
719
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
720
            zlog_debug ("Duplicated dbdesc causes retransmit");
 
721
          THREAD_OFF (on->thread_send_dbdesc);
 
722
          on->thread_send_dbdesc =
 
723
            thread_add_event (master, ospf6_dbdesc_send, on, 0);
 
724
          return;
 
725
        }
 
726
 
 
727
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
728
        zlog_debug ("Not duplicate dbdesc in state %s",
 
729
                    ospf6_neighbor_state_str[on->state]);
 
730
      thread_add_event (master, seqnumber_mismatch, on, 0);
 
731
      return;
 
732
 
 
733
    default:
 
734
      assert (0);
 
735
      break;
 
736
    }
 
737
 
 
738
  /* Process LSA headers */
 
739
  for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
 
740
       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
 
741
       p += sizeof (struct ospf6_lsa_header))
 
742
    {
 
743
      struct ospf6_lsa *his, *mine;
 
744
      struct ospf6_lsdb *lsdb = NULL;
 
745
 
 
746
      his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
 
747
 
 
748
      switch (OSPF6_LSA_SCOPE (his->header->type))
 
749
        {
 
750
        case OSPF6_SCOPE_LINKLOCAL:
 
751
          lsdb = on->ospf6_if->lsdb;
 
752
          break;
 
753
        case OSPF6_SCOPE_AREA:
 
754
          lsdb = on->ospf6_if->area->lsdb;
 
755
          break;
 
756
        case OSPF6_SCOPE_AS:
 
757
          lsdb = on->ospf6_if->area->ospf6->lsdb;
 
758
          break;
 
759
        case OSPF6_SCOPE_RESERVED:
 
760
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
761
            zlog_debug ("Ignoring LSA of reserved scope");
 
762
          ospf6_lsa_delete (his);
 
763
          continue;
 
764
          break;
 
765
        }
 
766
 
 
767
      if (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS &&
 
768
          IS_AREA_STUB (on->ospf6_if->area))
 
769
        {
 
770
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
771
            zlog_debug ("E-bit mismatch with LSA Headers");
 
772
          ospf6_lsa_delete (his);
 
773
          thread_add_event (master, seqnumber_mismatch, on, 0);
 
774
          return;
 
775
        }
 
776
 
 
777
      mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
 
778
                                his->header->adv_router, lsdb);
 
779
      if (mine == NULL || ospf6_lsa_compare (his, mine) < 0)
 
780
        {
 
781
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
782
            zlog_debug ("Add request-list: %s", his->name);
 
783
          ospf6_lsdb_add (his, on->request_list);
 
784
        }
 
785
      else
 
786
        ospf6_lsa_delete (his);
 
787
    }
 
788
 
 
789
  if (p != OSPF6_MESSAGE_END (oh))
 
790
    {
 
791
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
792
        zlog_debug ("Trailing garbage ignored");
 
793
    }
 
794
 
 
795
  /* Set sequence number to Master's */
 
796
  on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
 
797
 
 
798
  /* schedule send lsreq */
 
799
  if (on->thread_send_lsreq == NULL)
 
800
    on->thread_send_lsreq =
 
801
      thread_add_event (master, ospf6_lsreq_send, on, 0);
 
802
 
 
803
  THREAD_OFF (on->thread_send_dbdesc);
 
804
  on->thread_send_dbdesc =
 
805
    thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
 
806
 
 
807
  /* save last received dbdesc */
 
808
  memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
 
809
}
 
810
 
 
811
void
 
812
ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst,
 
813
                   struct ospf6_interface *oi, struct ospf6_header *oh)
 
814
{
 
815
  struct ospf6_neighbor *on;
 
816
  struct ospf6_dbdesc *dbdesc;
 
817
 
 
818
  if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
 
819
    return;
 
820
 
 
821
  on = ospf6_neighbor_lookup (oh->router_id, oi);
 
822
  if (on == NULL)
 
823
    {
 
824
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
825
        zlog_debug ("Neighbor not found, ignore");
 
826
      return;
 
827
    }
 
828
 
 
829
  if (memcmp (src, &on->linklocal_addr, sizeof (struct in6_addr)))
 
830
    {
 
831
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
832
        zlog_debug ("Seems to be from Secondary I/F of the neighbor, ignore");
 
833
      return;
 
834
    }
 
835
 
 
836
  dbdesc = (struct ospf6_dbdesc *)
 
837
    ((caddr_t) oh + sizeof (struct ospf6_header));
 
838
 
 
839
  /* Interface MTU check */
 
840
  if (ntohs (dbdesc->ifmtu) != oi->ifmtu)
 
841
    {
 
842
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
843
        zlog_debug ("I/F MTU mismatch");
 
844
      return;
 
845
    }
 
846
 
 
847
  if (dbdesc->reserved1 || dbdesc->reserved2)
 
848
    {
 
849
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
850
        zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
 
851
                    on->name);
 
852
      dbdesc->reserved1 = 0;
 
853
      dbdesc->reserved2 = 0;
 
854
    }
 
855
 
 
856
  if (ntohl (oh->router_id) < ntohl (ospf6->router_id))
 
857
    ospf6_dbdesc_recv_master (oh, on);
 
858
  else if (ntohl (ospf6->router_id) < ntohl (oh->router_id))
 
859
    ospf6_dbdesc_recv_slave (oh, on);
 
860
  else
 
861
    {
 
862
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
863
        zlog_debug ("Can't decide which is master, ignore");
 
864
    }
 
865
}
 
866
 
 
867
void
 
868
ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
 
869
                  struct ospf6_interface *oi, struct ospf6_header *oh)
 
870
{
 
871
  struct ospf6_neighbor *on;
 
872
  char *p;
 
873
  struct ospf6_lsreq_entry *e;
 
874
  struct ospf6_lsdb *lsdb = NULL;
 
875
  struct ospf6_lsa *lsa;
 
876
 
 
877
  if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
 
878
    return;
 
879
 
 
880
  on = ospf6_neighbor_lookup (oh->router_id, oi);
 
881
  if (on == NULL)
 
882
    {
 
883
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
884
        zlog_debug ("Neighbor not found, ignore");
 
885
      return;
 
886
    }
 
887
 
 
888
  if (memcmp (src, &on->linklocal_addr, sizeof (struct in6_addr)))
 
889
    {
 
890
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
891
        zlog_debug ("Seems to be from Secondary I/F of the neighbor, ignore");
 
892
      return;
 
893
    }
 
894
 
 
895
  if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
 
896
      on->state != OSPF6_NEIGHBOR_LOADING &&
 
897
      on->state != OSPF6_NEIGHBOR_FULL)
 
898
    {
 
899
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
900
        zlog_debug ("Neighbor state less than Exchange, ignore");
 
901
      return;
 
902
    }
 
903
 
 
904
  /* Process each request */
 
905
  for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
 
906
       p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
 
907
       p += sizeof (struct ospf6_lsreq_entry))
 
908
    {
 
909
      e = (struct ospf6_lsreq_entry *) p;
 
910
 
 
911
      switch (OSPF6_LSA_SCOPE (e->type))
 
912
        {
 
913
        case OSPF6_SCOPE_LINKLOCAL:
 
914
          lsdb = on->ospf6_if->lsdb;
 
915
          break;
 
916
        case OSPF6_SCOPE_AREA:
 
917
          lsdb = on->ospf6_if->area->lsdb;
 
918
          break;
 
919
        case OSPF6_SCOPE_AS:
 
920
          lsdb = on->ospf6_if->area->ospf6->lsdb;
 
921
          break;
 
922
        default:
 
923
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
924
            zlog_debug ("Ignoring LSA of reserved scope");
 
925
          continue;
 
926
          break;
 
927
        }
 
928
 
 
929
      /* Find database copy */
 
930
      lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb);
 
931
      if (lsa == NULL)
 
932
        {
 
933
          char id[16], adv_router[16];
 
934
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
935
            {
 
936
              inet_ntop (AF_INET, &e->id, id, sizeof (id));
 
937
              inet_ntop (AF_INET, &e->adv_router, adv_router,
 
938
                     sizeof (adv_router));
 
939
              zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
 
940
                          ospf6_lstype_name (e->type), id, adv_router);
 
941
            }
 
942
          thread_add_event (master, bad_lsreq, on, 0);
 
943
          return;
 
944
        }
 
945
 
 
946
      ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list);
 
947
    }
 
948
 
 
949
  if (p != OSPF6_MESSAGE_END (oh))
 
950
    {
 
951
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
952
        zlog_debug ("Trailing garbage ignored");
 
953
    }
 
954
 
 
955
  /* schedule send lsupdate */
 
956
  THREAD_OFF (on->thread_send_lsupdate);
 
957
  on->thread_send_lsupdate =
 
958
    thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
 
959
}
 
960
 
 
961
void
 
962
ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst,
 
963
                     struct ospf6_interface *oi, struct ospf6_header *oh)
 
964
{
 
965
  struct ospf6_neighbor *on;
 
966
  struct ospf6_lsupdate *lsupdate;
 
967
  unsigned long num;
 
968
  char *p;
 
969
 
 
970
  if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
 
971
    return;
 
972
 
 
973
  on = ospf6_neighbor_lookup (oh->router_id, oi);
 
974
  if (on == NULL)
 
975
    {
 
976
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
977
        zlog_debug ("Neighbor not found, ignore");
 
978
      return;
 
979
    }
 
980
 
 
981
  if (memcmp (src, &on->linklocal_addr, sizeof (struct in6_addr)))
 
982
    {
 
983
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
984
        zlog_debug ("Seems to be from Secondary I/F of the neighbor, ignore");
 
985
      return;
 
986
    }
 
987
 
 
988
  if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
 
989
      on->state != OSPF6_NEIGHBOR_LOADING &&
 
990
      on->state != OSPF6_NEIGHBOR_FULL)
 
991
    {
 
992
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
993
        zlog_debug ("Neighbor state less than Exchange, ignore");
 
994
      return;
 
995
    }
 
996
 
 
997
  lsupdate = (struct ospf6_lsupdate *)
 
998
    ((caddr_t) oh + sizeof (struct ospf6_header));
 
999
 
 
1000
  num = ntohl (lsupdate->lsa_number);
 
1001
 
 
1002
  /* Process LSAs */
 
1003
  for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
 
1004
       p < OSPF6_MESSAGE_END (oh) &&
 
1005
       p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
 
1006
       p += OSPF6_LSA_SIZE (p))
 
1007
    {
 
1008
      if (num == 0)
 
1009
        break;
 
1010
      if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header))
 
1011
        {
 
1012
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1013
            zlog_debug ("Malformed LSA length, quit processing");
 
1014
          break;
 
1015
        }
 
1016
 
 
1017
      ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p);
 
1018
      num--;
 
1019
    }
 
1020
 
 
1021
  if (num != 0)
 
1022
    {
 
1023
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1024
        zlog_debug ("Malformed LSA number or LSA length");
 
1025
    }
 
1026
  if (p != OSPF6_MESSAGE_END (oh))
 
1027
    {
 
1028
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1029
        zlog_debug ("Trailing garbage ignored");
 
1030
    }
 
1031
 
 
1032
  /* RFC2328 Section 10.9: When the neighbor responds to these requests
 
1033
     with the proper Link State Update packet(s), the Link state request
 
1034
     list is truncated and a new Link State Request packet is sent. */
 
1035
  /* send new Link State Request packet if this LS Update packet
 
1036
     can be recognized as a response to our previous LS Request */
 
1037
  if (! IN6_IS_ADDR_MULTICAST (dst) &&
 
1038
      (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
 
1039
       on->state == OSPF6_NEIGHBOR_LOADING))
 
1040
    {
 
1041
      THREAD_OFF (on->thread_send_lsreq);
 
1042
      on->thread_send_lsreq =
 
1043
        thread_add_event (master, ospf6_lsreq_send, on, 0);
 
1044
    }
 
1045
}
 
1046
 
 
1047
void
 
1048
ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst,
 
1049
                  struct ospf6_interface *oi, struct ospf6_header *oh)
 
1050
{
 
1051
  struct ospf6_neighbor *on;
 
1052
  char *p;
 
1053
  struct ospf6_lsa *his, *mine;
 
1054
  struct ospf6_lsdb *lsdb = NULL;
 
1055
 
 
1056
  assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
 
1057
  if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
 
1058
    return;
 
1059
 
 
1060
  on = ospf6_neighbor_lookup (oh->router_id, oi);
 
1061
  if (on == NULL)
 
1062
    {
 
1063
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1064
        zlog_debug ("Neighbor not found, ignore");
 
1065
      return;
 
1066
    }
 
1067
 
 
1068
  if (memcmp (src, &on->linklocal_addr, sizeof (struct in6_addr)))
 
1069
    {
 
1070
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1071
        zlog_debug ("Seems to be from Secondary I/F of the neighbor, ignore");
 
1072
      return;
 
1073
    }
 
1074
 
 
1075
  if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
 
1076
      on->state != OSPF6_NEIGHBOR_LOADING &&
 
1077
      on->state != OSPF6_NEIGHBOR_FULL)
 
1078
    {
 
1079
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1080
        zlog_debug ("Neighbor state less than Exchange, ignore");
 
1081
      return;
 
1082
    }
 
1083
 
 
1084
  for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
 
1085
       p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
 
1086
       p += sizeof (struct ospf6_lsa_header))
 
1087
    {
 
1088
      his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
 
1089
 
 
1090
      switch (OSPF6_LSA_SCOPE (his->header->type))
 
1091
        {
 
1092
        case OSPF6_SCOPE_LINKLOCAL:
 
1093
          lsdb = on->ospf6_if->lsdb;
 
1094
          break;
 
1095
        case OSPF6_SCOPE_AREA:
 
1096
          lsdb = on->ospf6_if->area->lsdb;
 
1097
          break;
 
1098
        case OSPF6_SCOPE_AS:
 
1099
          lsdb = on->ospf6_if->area->ospf6->lsdb;
 
1100
          break;
 
1101
        case OSPF6_SCOPE_RESERVED:
 
1102
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1103
            zlog_debug ("Ignoring LSA of reserved scope");
 
1104
          ospf6_lsa_delete (his);
 
1105
          continue;
 
1106
          break;
 
1107
        }
 
1108
 
 
1109
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1110
        zlog_debug ("%s acknowledged by %s", his->name, on->name);
 
1111
 
 
1112
      /* Find database copy */
 
1113
      mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
 
1114
                                his->header->adv_router, lsdb);
 
1115
      if (mine == NULL)
 
1116
        {
 
1117
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1118
            zlog_debug ("No database copy");
 
1119
          ospf6_lsa_delete (his);
 
1120
          continue;
 
1121
        }
 
1122
 
 
1123
      /* Check if the LSA is on his retrans-list */
 
1124
      mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
 
1125
                                his->header->adv_router, on->retrans_list);
 
1126
      if (mine == NULL)
 
1127
        {
 
1128
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1129
            zlog_debug ("Not on %s's retrans-list", on->name);
 
1130
          ospf6_lsa_delete (his);
 
1131
          continue;
 
1132
        }
 
1133
 
 
1134
      if (ospf6_lsa_compare (his, mine) != 0)
 
1135
        {
 
1136
          /* Log this questionable acknowledgement,
 
1137
             and examine the next one. */
 
1138
          if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1139
            zlog_debug ("Questionable acknowledgement");
 
1140
          ospf6_lsa_delete (his);
 
1141
          continue;
 
1142
        }
 
1143
 
 
1144
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1145
        zlog_debug ("Acknowledged, remove from %s's retrans-list",
 
1146
                    on->name);
 
1147
 
 
1148
      if (OSPF6_LSA_IS_MAXAGE (mine))
 
1149
        ospf6_maxage_remove (on->ospf6_if->area->ospf6);
 
1150
 
 
1151
      ospf6_decrement_retrans_count (mine);
 
1152
      ospf6_lsdb_remove (mine, on->retrans_list);
 
1153
      ospf6_lsa_delete (his);
 
1154
    }
 
1155
 
 
1156
  if (p != OSPF6_MESSAGE_END (oh))
 
1157
    {
 
1158
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1159
        zlog_debug ("Trailing garbage ignored");
 
1160
    }
 
1161
}
 
1162
 
 
1163
u_char *recvbuf = NULL;
 
1164
u_char *sendbuf = NULL;
 
1165
unsigned int iobuflen = 0;
 
1166
 
 
1167
int
 
1168
ospf6_iobuf_size (unsigned int size)
 
1169
{
 
1170
  char *recvnew, *sendnew;
 
1171
 
 
1172
  if (size <= iobuflen)
 
1173
    return iobuflen;
 
1174
 
 
1175
  recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
 
1176
  sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
 
1177
  if (recvnew == NULL || sendnew == NULL)
 
1178
    {
 
1179
      if (recvnew)
 
1180
        XFREE (MTYPE_OSPF6_MESSAGE, recvnew);
 
1181
      if (sendnew)
 
1182
        XFREE (MTYPE_OSPF6_MESSAGE, sendnew);
 
1183
      zlog_debug ("Could not allocate I/O buffer of size %d.", size);
 
1184
      return iobuflen;
 
1185
    }
 
1186
 
 
1187
  if (recvbuf)
 
1188
    XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
 
1189
  if (sendbuf)
 
1190
    XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
 
1191
  recvbuf = recvnew;
 
1192
  sendbuf = sendnew;
 
1193
  iobuflen = size;
 
1194
 
 
1195
  return iobuflen;
 
1196
}
 
1197
 
 
1198
int
 
1199
ospf6_receive (struct thread *thread)
 
1200
{
 
1201
  int sockfd;
 
1202
  unsigned int len;
 
1203
  char srcname[64], dstname[64];
 
1204
  struct in6_addr src, dst;
 
1205
  unsigned int ifindex;
 
1206
  struct iovec iovector[2];
 
1207
  struct ospf6_interface *oi;
 
1208
  struct ospf6_header *oh;
 
1209
 
 
1210
  /* add next read thread */
 
1211
  sockfd = THREAD_FD (thread);
 
1212
  thread_add_read (master, ospf6_receive, NULL, sockfd);
 
1213
 
 
1214
  /* initialize */
 
1215
  memset (recvbuf, 0, iobuflen);
 
1216
  iovector[0].iov_base = recvbuf;
 
1217
  iovector[0].iov_len = iobuflen;
 
1218
  iovector[1].iov_base = NULL;
 
1219
  iovector[1].iov_len = 0;
 
1220
 
 
1221
  /* receive message */
 
1222
  len = ospf6_recvmsg (&src, &dst, &ifindex, iovector);
 
1223
  if (len > iobuflen)
 
1224
    {
 
1225
      zlog_err ("Excess message read");
 
1226
      return 0;
 
1227
    }
 
1228
  else if (len < sizeof (struct ospf6_header))
 
1229
    {
 
1230
      zlog_err ("Deficient message read");
 
1231
      return 0;
 
1232
    }
 
1233
 
 
1234
  oi = ospf6_interface_lookup_by_ifindex (ifindex);
 
1235
  if (oi == NULL || oi->area == NULL)
 
1236
    {
 
1237
      zlog_debug ("Message received on disabled interface");
 
1238
      return 0;
 
1239
    }
 
1240
 
 
1241
  oh = (struct ospf6_header *) recvbuf;
 
1242
 
 
1243
  /* Log */
 
1244
  if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1245
    {
 
1246
      inet_ntop (AF_INET6, &src, srcname, sizeof (srcname));
 
1247
      inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname));
 
1248
      zlog_debug ("%s received on %s",
 
1249
                 OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
 
1250
      zlog_debug ("    src: %s", srcname);
 
1251
      zlog_debug ("    dst: %s", dstname);
 
1252
      if (len != ntohs (oh->length))
 
1253
        zlog_debug ("Message length does not match actually received: %d", len);
 
1254
 
 
1255
      switch (oh->type)
 
1256
        {
 
1257
          case OSPF6_MESSAGE_TYPE_HELLO:
 
1258
            ospf6_hello_print (oh);
 
1259
            break;
 
1260
          case OSPF6_MESSAGE_TYPE_DBDESC:
 
1261
            ospf6_dbdesc_print (oh);
 
1262
            break;
 
1263
          case OSPF6_MESSAGE_TYPE_LSREQ:
 
1264
            ospf6_lsreq_print (oh);
 
1265
            break;
 
1266
          case OSPF6_MESSAGE_TYPE_LSUPDATE:
 
1267
            ospf6_lsupdate_print (oh);
 
1268
            break;
 
1269
          case OSPF6_MESSAGE_TYPE_LSACK:
 
1270
            ospf6_lsack_print (oh);
 
1271
            break;
 
1272
          default:
 
1273
            zlog_debug ("Unknown message");
 
1274
            break;
 
1275
        }
 
1276
    }
 
1277
 
 
1278
  if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
 
1279
    {
 
1280
      if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
 
1281
        zlog_debug ("Ignore message on passive interface %s",
 
1282
                   oi->interface->name);
 
1283
      return 0;
 
1284
    }
 
1285
 
 
1286
  switch (oh->type)
 
1287
    {
 
1288
      case OSPF6_MESSAGE_TYPE_HELLO:
 
1289
        ospf6_hello_recv (&src, &dst, oi, oh);
 
1290
        break;
 
1291
 
 
1292
      case OSPF6_MESSAGE_TYPE_DBDESC:
 
1293
        ospf6_dbdesc_recv (&src, &dst, oi, oh);
 
1294
        break;
 
1295
 
 
1296
      case OSPF6_MESSAGE_TYPE_LSREQ:
 
1297
        ospf6_lsreq_recv (&src, &dst, oi, oh);
 
1298
        break;
 
1299
 
 
1300
      case OSPF6_MESSAGE_TYPE_LSUPDATE:
 
1301
        ospf6_lsupdate_recv (&src, &dst, oi, oh);
 
1302
        break;
 
1303
 
 
1304
      case OSPF6_MESSAGE_TYPE_LSACK:
 
1305
        ospf6_lsack_recv (&src, &dst, oi, oh);
 
1306
        break;
 
1307
 
 
1308
      default:
 
1309
        if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
 
1310
          zlog_debug ("Unknown message");
 
1311
        break;
 
1312
    }
 
1313
 
 
1314
  return 0;
 
1315
}
 
1316
 
 
1317
void
 
1318
ospf6_send (struct in6_addr *src, struct in6_addr *dst,
 
1319
            struct ospf6_interface *oi, struct ospf6_header *oh)
 
1320
{
 
1321
  int len;
 
1322
  char srcname[64], dstname[64];
 
1323
  struct iovec iovector[2];
 
1324
 
 
1325
  /* initialize */
 
1326
  iovector[0].iov_base = (caddr_t) oh;
 
1327
  iovector[0].iov_len = ntohs (oh->length);
 
1328
  iovector[1].iov_base = NULL;
 
1329
  iovector[1].iov_len = 0;
 
1330
 
 
1331
  /* fill OSPF header */
 
1332
  oh->version = OSPFV3_VERSION;
 
1333
  /* message type must be set before */
 
1334
  /* message length must be set before */
 
1335
  oh->router_id = oi->area->ospf6->router_id;
 
1336
  oh->area_id = oi->area->area_id;
 
1337
  /* checksum is calculated by kernel */
 
1338
  oh->instance_id = oi->instance_id;
 
1339
  oh->reserved = 0;
 
1340
 
 
1341
  /* Log */
 
1342
  if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND))
 
1343
    {
 
1344
      inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));
 
1345
      if (src)
 
1346
        inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
 
1347
      else
 
1348
        memset (srcname, 0, sizeof (srcname));
 
1349
      zlog_debug ("%s send on %s",
 
1350
                 OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
 
1351
      zlog_debug ("    src: %s", srcname);
 
1352
      zlog_debug ("    dst: %s", dstname);
 
1353
 
 
1354
      switch (oh->type)
 
1355
        {
 
1356
          case OSPF6_MESSAGE_TYPE_HELLO:
 
1357
            ospf6_hello_print (oh);
 
1358
            break;
 
1359
          case OSPF6_MESSAGE_TYPE_DBDESC:
 
1360
            ospf6_dbdesc_print (oh);
 
1361
            break;
 
1362
          case OSPF6_MESSAGE_TYPE_LSREQ:
 
1363
            ospf6_lsreq_print (oh);
 
1364
            break;
 
1365
          case OSPF6_MESSAGE_TYPE_LSUPDATE:
 
1366
            ospf6_lsupdate_print (oh);
 
1367
            break;
 
1368
          case OSPF6_MESSAGE_TYPE_LSACK:
 
1369
            ospf6_lsack_print (oh);
 
1370
            break;
 
1371
          default:
 
1372
            zlog_debug ("Unknown message");
 
1373
            assert (0);
 
1374
            break;
 
1375
        }
 
1376
    }
 
1377
 
 
1378
  /* send message */
 
1379
  len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector);
 
1380
  if (len != ntohs (oh->length))
 
1381
    zlog_err ("Could not send entire message");
 
1382
}
 
1383
 
 
1384
int
 
1385
ospf6_hello_send (struct thread *thread)
 
1386
{
 
1387
  struct ospf6_interface *oi;
 
1388
  struct ospf6_header *oh;
 
1389
  struct ospf6_hello *hello;
 
1390
  u_char *p;
 
1391
  struct listnode *node, *nnode;
 
1392
  struct ospf6_neighbor *on;
 
1393
 
 
1394
  oi = (struct ospf6_interface *) THREAD_ARG (thread);
 
1395
  oi->thread_send_hello = (struct thread *) NULL;
 
1396
 
 
1397
  if (oi->state <= OSPF6_INTERFACE_DOWN)
 
1398
    {
 
1399
      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
 
1400
        zlog_debug ("Unable to send Hello on down interface %s",
 
1401
                   oi->interface->name);
 
1402
      return 0;
 
1403
    }
 
1404
 
 
1405
  /* set next thread */
 
1406
  oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,
 
1407
                                            oi, oi->hello_interval);
 
1408
 
 
1409
  memset (sendbuf, 0, iobuflen);
 
1410
  oh = (struct ospf6_header *) sendbuf;
 
1411
  hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header));
 
1412
 
 
1413
  hello->interface_id = htonl (oi->interface->ifindex);
 
1414
  hello->priority = oi->priority;
 
1415
  hello->options[0] = oi->area->options[0];
 
1416
  hello->options[1] = oi->area->options[1];
 
1417
  hello->options[2] = oi->area->options[2];
 
1418
  hello->hello_interval = htons (oi->hello_interval);
 
1419
  hello->dead_interval = htons (oi->dead_interval);
 
1420
  hello->drouter = oi->drouter;
 
1421
  hello->bdrouter = oi->bdrouter;
 
1422
 
 
1423
  p = (char *)((caddr_t) hello + sizeof (struct ospf6_hello));
 
1424
 
 
1425
  for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
 
1426
    {
 
1427
      if (on->state < OSPF6_NEIGHBOR_INIT)
 
1428
        continue;
 
1429
 
 
1430
      if (p - sendbuf + sizeof (u_int32_t) > oi->ifmtu)
 
1431
        {
 
1432
          if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
 
1433
            zlog_debug ("sending Hello message: exceeds I/F MTU");
 
1434
          break;
 
1435
        }
 
1436
 
 
1437
      memcpy (p, &on->router_id, sizeof (u_int32_t));
 
1438
      p += sizeof (u_int32_t);
 
1439
    }
 
1440
 
 
1441
  oh->type = OSPF6_MESSAGE_TYPE_HELLO;
 
1442
  oh->length = htons (p - sendbuf);
 
1443
 
 
1444
  ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
 
1445
  return 0;
 
1446
}
 
1447
 
 
1448
int
 
1449
ospf6_dbdesc_send (struct thread *thread)
 
1450
{
 
1451
  struct ospf6_neighbor *on;
 
1452
  struct ospf6_header *oh;
 
1453
  struct ospf6_dbdesc *dbdesc;
 
1454
  u_char *p;
 
1455
  struct ospf6_lsa *lsa;
 
1456
 
 
1457
  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
1458
  on->thread_send_dbdesc = (struct thread *) NULL;
 
1459
 
 
1460
  if (on->state < OSPF6_NEIGHBOR_EXSTART)
 
1461
    {
 
1462
      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND))
 
1463
        zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
 
1464
                    on->name, ospf6_neighbor_state_str[on->state]);
 
1465
      return 0;
 
1466
    }
 
1467
 
 
1468
  /* set next thread if master */
 
1469
  if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
 
1470
    on->thread_send_dbdesc =
 
1471
      thread_add_timer (master, ospf6_dbdesc_send, on,
 
1472
                        on->ospf6_if->rxmt_interval);
 
1473
 
 
1474
  memset (sendbuf, 0, iobuflen);
 
1475
  oh = (struct ospf6_header *) sendbuf;
 
1476
  dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh +
 
1477
                                   sizeof (struct ospf6_header));
 
1478
 
 
1479
  /* if this is initial one, initialize sequence number for DbDesc */
 
1480
  if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
 
1481
    {
 
1482
      struct timeval tv;
 
1483
      if (gettimeofday (&tv, (struct timezone *) NULL) < 0)
 
1484
        tv.tv_sec = 1;
 
1485
      on->dbdesc_seqnum = tv.tv_sec;
 
1486
    }
 
1487
 
 
1488
  dbdesc->options[0] = on->ospf6_if->area->options[0];
 
1489
  dbdesc->options[1] = on->ospf6_if->area->options[1];
 
1490
  dbdesc->options[2] = on->ospf6_if->area->options[2];
 
1491
  dbdesc->ifmtu = htons (on->ospf6_if->ifmtu);
 
1492
  dbdesc->bits = on->dbdesc_bits;
 
1493
  dbdesc->seqnum = htonl (on->dbdesc_seqnum);
 
1494
 
 
1495
  /* if this is not initial one, set LSA headers in dbdesc */
 
1496
  p = (char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
 
1497
  if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
 
1498
    {
 
1499
      for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
 
1500
           lsa = ospf6_lsdb_next (lsa))
 
1501
        {
 
1502
          ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
 
1503
 
 
1504
          /* MTU check */
 
1505
          if (p - sendbuf + sizeof (struct ospf6_lsa_header) >
 
1506
              on->ospf6_if->ifmtu)
 
1507
            {
 
1508
              ospf6_lsa_unlock (lsa);
 
1509
              break;
 
1510
            }
 
1511
          memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
 
1512
          p += sizeof (struct ospf6_lsa_header);
 
1513
        }
 
1514
    }
 
1515
 
 
1516
  oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
 
1517
  oh->length = htons (p - sendbuf);
 
1518
 
 
1519
  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
 
1520
              on->ospf6_if, oh);
 
1521
  return 0;
 
1522
}
 
1523
 
 
1524
int
 
1525
ospf6_dbdesc_send_newone (struct thread *thread)
 
1526
{
 
1527
  struct ospf6_neighbor *on;
 
1528
  struct ospf6_lsa *lsa;
 
1529
  unsigned int size = 0;
 
1530
 
 
1531
  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
1532
  ospf6_lsdb_remove_all (on->dbdesc_list);
 
1533
 
 
1534
  /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
 
1535
     so that ospf6_send_dbdesc () can send those LSAs */
 
1536
  size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc);
 
1537
  for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
 
1538
       lsa = ospf6_lsdb_next (lsa))
 
1539
    {
 
1540
      if (size + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu)
 
1541
        {
 
1542
          ospf6_lsa_unlock (lsa);
 
1543
          break;
 
1544
        }
 
1545
 
 
1546
      ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list);
 
1547
      ospf6_lsdb_remove (lsa, on->summary_list);
 
1548
      size += sizeof (struct ospf6_lsa_header);
 
1549
    }
 
1550
 
 
1551
  if (on->summary_list->count == 0)
 
1552
    UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
 
1553
 
 
1554
  /* If slave, More bit check must be done here */
 
1555
  if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
 
1556
      ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) &&
 
1557
      ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
 
1558
    thread_add_event (master, exchange_done, on, 0);
 
1559
 
 
1560
  thread_execute (master, ospf6_dbdesc_send, on, 0);
 
1561
  return 0;
 
1562
}
 
1563
 
 
1564
int
 
1565
ospf6_lsreq_send (struct thread *thread)
 
1566
{
 
1567
  struct ospf6_neighbor *on;
 
1568
  struct ospf6_header *oh;
 
1569
  struct ospf6_lsreq_entry *e;
 
1570
  u_char *p;
 
1571
  struct ospf6_lsa *lsa;
 
1572
 
 
1573
  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
1574
  on->thread_send_lsreq = (struct thread *) NULL;
 
1575
 
 
1576
  /* LSReq will be sent only in ExStart or Loading */
 
1577
  if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
 
1578
      on->state != OSPF6_NEIGHBOR_LOADING)
 
1579
    {
 
1580
      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND))
 
1581
        zlog_debug ("Quit to send LSReq to neighbor %s state %s",
 
1582
                    on->name, ospf6_neighbor_state_str[on->state]);
 
1583
      return 0;
 
1584
    }
 
1585
 
 
1586
  /* schedule loading_done if request list is empty */
 
1587
  if (on->request_list->count == 0)
 
1588
    {
 
1589
      thread_add_event (master, loading_done, on, 0);
 
1590
      return 0;
 
1591
    }
 
1592
 
 
1593
  /* set next thread */
 
1594
  on->thread_send_lsreq =
 
1595
    thread_add_timer (master, ospf6_lsreq_send, on,
 
1596
                      on->ospf6_if->rxmt_interval);
 
1597
 
 
1598
  memset (sendbuf, 0, iobuflen);
 
1599
  oh = (struct ospf6_header *) sendbuf;
 
1600
 
 
1601
  /* set Request entries in lsreq */
 
1602
  p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));
 
1603
  for (lsa = ospf6_lsdb_head (on->request_list); lsa;
 
1604
       lsa = ospf6_lsdb_next (lsa))
 
1605
    {
 
1606
      /* MTU check */
 
1607
      if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > on->ospf6_if->ifmtu)
 
1608
        {
 
1609
          ospf6_lsa_unlock (lsa);
 
1610
          break;
 
1611
        }
 
1612
 
 
1613
      e = (struct ospf6_lsreq_entry *) p;
 
1614
      e->type = lsa->header->type;
 
1615
      e->id = lsa->header->id;
 
1616
      e->adv_router = lsa->header->adv_router;
 
1617
      p += sizeof (struct ospf6_lsreq_entry);
 
1618
    }
 
1619
 
 
1620
  oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
 
1621
  oh->length = htons (p - sendbuf);
 
1622
 
 
1623
  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
 
1624
              on->ospf6_if, oh);
 
1625
  return 0;
 
1626
}
 
1627
 
 
1628
int
 
1629
ospf6_lsupdate_send_neighbor (struct thread *thread)
 
1630
{
 
1631
  struct ospf6_neighbor *on;
 
1632
  struct ospf6_header *oh;
 
1633
  struct ospf6_lsupdate *lsupdate;
 
1634
  u_char *p;
 
1635
  int num;
 
1636
  struct ospf6_lsa *lsa;
 
1637
 
 
1638
  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
1639
  on->thread_send_lsupdate = (struct thread *) NULL;
 
1640
 
 
1641
  if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
 
1642
    zlog_debug ("LSUpdate to neighbor %s", on->name);
 
1643
 
 
1644
  if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
 
1645
    {
 
1646
      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
 
1647
        zlog_debug ("Quit to send (neighbor state %s)",
 
1648
                    ospf6_neighbor_state_str[on->state]);
 
1649
      return 0;
 
1650
    }
 
1651
 
 
1652
  /* if we have nothing to send, return */
 
1653
  if (on->lsupdate_list->count == 0 &&
 
1654
      on->retrans_list->count == 0)
 
1655
    {
 
1656
      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
 
1657
        zlog_debug ("Quit to send (nothing to send)");
 
1658
      return 0;
 
1659
    }
 
1660
 
 
1661
  memset (sendbuf, 0, iobuflen);
 
1662
  oh = (struct ospf6_header *) sendbuf;
 
1663
  lsupdate = (struct ospf6_lsupdate *)
 
1664
    ((caddr_t) oh + sizeof (struct ospf6_header));
 
1665
 
 
1666
  p = (char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
 
1667
  num = 0;
 
1668
 
 
1669
  /* lsupdate_list lists those LSA which doesn't need to be
 
1670
     retransmitted. remove those from the list */
 
1671
  for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
 
1672
       lsa = ospf6_lsdb_next (lsa))
 
1673
    {
 
1674
      /* MTU check */
 
1675
      if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
 
1676
          > on->ospf6_if->ifmtu)
 
1677
        {
 
1678
          ospf6_lsa_unlock (lsa);
 
1679
          break;
 
1680
        }
 
1681
 
 
1682
      ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
 
1683
      memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
 
1684
      p += OSPF6_LSA_SIZE (lsa->header);
 
1685
      num++;
 
1686
 
 
1687
      assert (lsa->lock == 2);
 
1688
      ospf6_lsdb_remove (lsa, on->lsupdate_list);
 
1689
    }
 
1690
 
 
1691
  for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
 
1692
       lsa = ospf6_lsdb_next (lsa))
 
1693
    {
 
1694
      /* MTU check */
 
1695
      if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
 
1696
          > on->ospf6_if->ifmtu)
 
1697
        {
 
1698
          ospf6_lsa_unlock (lsa);
 
1699
          break;
 
1700
        }
 
1701
 
 
1702
      ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
 
1703
      memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
 
1704
      p += OSPF6_LSA_SIZE (lsa->header);
 
1705
      num++;
 
1706
    }
 
1707
 
 
1708
  lsupdate->lsa_number = htonl (num);
 
1709
 
 
1710
  oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
 
1711
  oh->length = htons (p - sendbuf);
 
1712
 
 
1713
  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
 
1714
              on->ospf6_if, oh);
 
1715
 
 
1716
  if (on->lsupdate_list->count != 0 ||
 
1717
      on->retrans_list->count != 0)
 
1718
    {
 
1719
      if (on->lsupdate_list->count != 0)
 
1720
        on->thread_send_lsupdate =
 
1721
          thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
 
1722
      else
 
1723
        on->thread_send_lsupdate =
 
1724
          thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
 
1725
                            on->ospf6_if->rxmt_interval);
 
1726
    }
 
1727
 
 
1728
  return 0;
 
1729
}
 
1730
 
 
1731
int
 
1732
ospf6_lsupdate_send_interface (struct thread *thread)
 
1733
{
 
1734
  struct ospf6_interface *oi;
 
1735
  struct ospf6_header *oh;
 
1736
  struct ospf6_lsupdate *lsupdate;
 
1737
  u_char *p;
 
1738
  int num;
 
1739
  struct ospf6_lsa *lsa;
 
1740
 
 
1741
  oi = (struct ospf6_interface *) THREAD_ARG (thread);
 
1742
  oi->thread_send_lsupdate = (struct thread *) NULL;
 
1743
 
 
1744
  if (oi->state <= OSPF6_INTERFACE_WAITING)
 
1745
    {
 
1746
      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
 
1747
        zlog_debug ("Quit to send LSUpdate to interface %s state %s",
 
1748
                    oi->interface->name, ospf6_interface_state_str[oi->state]);
 
1749
      return 0;
 
1750
    }
 
1751
 
 
1752
  /* if we have nothing to send, return */
 
1753
  if (oi->lsupdate_list->count == 0)
 
1754
    return 0;
 
1755
 
 
1756
  memset (sendbuf, 0, iobuflen);
 
1757
  oh = (struct ospf6_header *) sendbuf;
 
1758
  lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
 
1759
                                       sizeof (struct ospf6_header));
 
1760
 
 
1761
  p = (char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
 
1762
  num = 0;
 
1763
 
 
1764
  for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
 
1765
       lsa = ospf6_lsdb_next (lsa))
 
1766
    {
 
1767
      /* MTU check */
 
1768
      if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
 
1769
          > oi->ifmtu)
 
1770
        {
 
1771
          ospf6_lsa_unlock (lsa);
 
1772
          break;
 
1773
        }
 
1774
 
 
1775
      ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
 
1776
      memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
 
1777
      p += OSPF6_LSA_SIZE (lsa->header);
 
1778
      num++;
 
1779
 
 
1780
      assert (lsa->lock == 2);
 
1781
      ospf6_lsdb_remove (lsa, oi->lsupdate_list);
 
1782
    }
 
1783
 
 
1784
  lsupdate->lsa_number = htonl (num);
 
1785
 
 
1786
  oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
 
1787
  oh->length = htons (p - sendbuf);
 
1788
 
 
1789
  if (oi->state == OSPF6_INTERFACE_DR ||
 
1790
      oi->state == OSPF6_INTERFACE_BDR)
 
1791
    ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
 
1792
  else
 
1793
    ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
 
1794
 
 
1795
  if (oi->lsupdate_list->count > 0)
 
1796
    {
 
1797
      oi->thread_send_lsupdate =
 
1798
        thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
 
1799
    }
 
1800
 
 
1801
  return 0;
 
1802
}
 
1803
 
 
1804
int
 
1805
ospf6_lsack_send_neighbor (struct thread *thread)
 
1806
{
 
1807
  struct ospf6_neighbor *on;
 
1808
  struct ospf6_header *oh;
 
1809
  u_char *p;
 
1810
  struct ospf6_lsa *lsa;
 
1811
 
 
1812
  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
1813
  on->thread_send_lsack = (struct thread *) NULL;
 
1814
 
 
1815
  if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
 
1816
    {
 
1817
      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
 
1818
        zlog_debug ("Quit to send LSAck to neighbor %s state %s",
 
1819
                    on->name, ospf6_neighbor_state_str[on->state]);
 
1820
      return 0;
 
1821
    }
 
1822
 
 
1823
  /* if we have nothing to send, return */
 
1824
  if (on->lsack_list->count == 0)
 
1825
    return 0;
 
1826
 
 
1827
  memset (sendbuf, 0, iobuflen);
 
1828
  oh = (struct ospf6_header *) sendbuf;
 
1829
 
 
1830
  p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));
 
1831
 
 
1832
  for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
 
1833
       lsa = ospf6_lsdb_next (lsa))
 
1834
    {
 
1835
      /* MTU check */
 
1836
      if (p - sendbuf + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu)
 
1837
        {
 
1838
          /* if we run out of packet size/space here,
 
1839
             better to try again soon. */
 
1840
          THREAD_OFF (on->thread_send_lsack);
 
1841
          on->thread_send_lsack =
 
1842
            thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
 
1843
 
 
1844
          ospf6_lsa_unlock (lsa);
 
1845
          break;
 
1846
        }
 
1847
 
 
1848
      ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
 
1849
      memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
 
1850
      p += sizeof (struct ospf6_lsa_header);
 
1851
 
 
1852
      assert (lsa->lock == 2);
 
1853
      ospf6_lsdb_remove (lsa, on->lsack_list);
 
1854
    }
 
1855
 
 
1856
  oh->type = OSPF6_MESSAGE_TYPE_LSACK;
 
1857
  oh->length = htons (p - sendbuf);
 
1858
 
 
1859
  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
 
1860
              on->ospf6_if, oh);
 
1861
  return 0;
 
1862
}
 
1863
 
 
1864
int
 
1865
ospf6_lsack_send_interface (struct thread *thread)
 
1866
{
 
1867
  struct ospf6_interface *oi;
 
1868
  struct ospf6_header *oh;
 
1869
  u_char *p;
 
1870
  struct ospf6_lsa *lsa;
 
1871
 
 
1872
  oi = (struct ospf6_interface *) THREAD_ARG (thread);
 
1873
  oi->thread_send_lsack = (struct thread *) NULL;
 
1874
 
 
1875
  if (oi->state <= OSPF6_INTERFACE_WAITING)
 
1876
    {
 
1877
      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
 
1878
        zlog_debug ("Quit to send LSAck to interface %s state %s",
 
1879
                    oi->interface->name, ospf6_interface_state_str[oi->state]);
 
1880
      return 0;
 
1881
    }
 
1882
 
 
1883
  /* if we have nothing to send, return */
 
1884
  if (oi->lsack_list->count == 0)
 
1885
    return 0;
 
1886
 
 
1887
  memset (sendbuf, 0, iobuflen);
 
1888
  oh = (struct ospf6_header *) sendbuf;
 
1889
 
 
1890
  p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));
 
1891
 
 
1892
  for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
 
1893
       lsa = ospf6_lsdb_next (lsa))
 
1894
    {
 
1895
      /* MTU check */
 
1896
      if (p - sendbuf + sizeof (struct ospf6_lsa_header) > oi->ifmtu)
 
1897
        {
 
1898
          /* if we run out of packet size/space here,
 
1899
             better to try again soon. */
 
1900
          THREAD_OFF (oi->thread_send_lsack);
 
1901
          oi->thread_send_lsack =
 
1902
            thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
 
1903
 
 
1904
          ospf6_lsa_unlock (lsa);
 
1905
          break;
 
1906
        }
 
1907
 
 
1908
      ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
 
1909
      memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
 
1910
      p += sizeof (struct ospf6_lsa_header);
 
1911
 
 
1912
      assert (lsa->lock == 2);
 
1913
      ospf6_lsdb_remove (lsa, oi->lsack_list);
 
1914
    }
 
1915
 
 
1916
  oh->type = OSPF6_MESSAGE_TYPE_LSACK;
 
1917
  oh->length = htons (p - sendbuf);
 
1918
 
 
1919
  if (oi->state == OSPF6_INTERFACE_DR ||
 
1920
      oi->state == OSPF6_INTERFACE_BDR)
 
1921
    ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
 
1922
  else
 
1923
    ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
 
1924
 
 
1925
  if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
 
1926
    {
 
1927
      oi->thread_send_lsack =
 
1928
        thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
 
1929
    }
 
1930
 
 
1931
  return 0;
 
1932
}
 
1933
 
 
1934
 
 
1935
/* Commands */
 
1936
DEFUN (debug_ospf6_message,
 
1937
       debug_ospf6_message_cmd,
 
1938
       "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
 
1939
       DEBUG_STR
 
1940
       OSPF6_STR
 
1941
       "Debug OSPFv3 message\n"
 
1942
       "Debug Unknown message\n"
 
1943
       "Debug Hello message\n"
 
1944
       "Debug Database Description message\n"
 
1945
       "Debug Link State Request message\n"
 
1946
       "Debug Link State Update message\n"
 
1947
       "Debug Link State Acknowledgement message\n"
 
1948
       "Debug All message\n"
 
1949
       )
 
1950
{
 
1951
  unsigned char level = 0;
 
1952
  int type = 0;
 
1953
  int i;
 
1954
 
 
1955
  assert (argc > 0);
 
1956
 
 
1957
  /* check type */
 
1958
  if (! strncmp (argv[0], "u", 1))
 
1959
    type = OSPF6_MESSAGE_TYPE_UNKNOWN;
 
1960
  else if (! strncmp (argv[0], "h", 1))
 
1961
    type = OSPF6_MESSAGE_TYPE_HELLO;
 
1962
  else if (! strncmp (argv[0], "d", 1))
 
1963
    type = OSPF6_MESSAGE_TYPE_DBDESC;
 
1964
  else if (! strncmp (argv[0], "lsr", 3))
 
1965
    type = OSPF6_MESSAGE_TYPE_LSREQ;
 
1966
  else if (! strncmp (argv[0], "lsu", 3))
 
1967
    type = OSPF6_MESSAGE_TYPE_LSUPDATE;
 
1968
  else if (! strncmp (argv[0], "lsa", 3))
 
1969
    type = OSPF6_MESSAGE_TYPE_LSACK;
 
1970
  else if (! strncmp (argv[0], "a", 1))
 
1971
    type = OSPF6_MESSAGE_TYPE_ALL;
 
1972
 
 
1973
  if (argc == 1)
 
1974
    level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
 
1975
  else if (! strncmp (argv[1], "s", 1))
 
1976
    level = OSPF6_DEBUG_MESSAGE_SEND;
 
1977
  else if (! strncmp (argv[1], "r", 1))
 
1978
    level = OSPF6_DEBUG_MESSAGE_RECV;
 
1979
 
 
1980
  if (type == OSPF6_MESSAGE_TYPE_ALL)
 
1981
    {
 
1982
      for (i = 0; i < 6; i++)
 
1983
        OSPF6_DEBUG_MESSAGE_ON (i, level);
 
1984
    }
 
1985
  else
 
1986
    OSPF6_DEBUG_MESSAGE_ON (type, level);
 
1987
 
 
1988
  return CMD_SUCCESS;
 
1989
}
 
1990
 
 
1991
ALIAS (debug_ospf6_message,
 
1992
       debug_ospf6_message_sendrecv_cmd,
 
1993
       "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
 
1994
       DEBUG_STR
 
1995
       OSPF6_STR
 
1996
       "Debug OSPFv3 message\n"
 
1997
       "Debug Unknown message\n"
 
1998
       "Debug Hello message\n"
 
1999
       "Debug Database Description message\n"
 
2000
       "Debug Link State Request message\n"
 
2001
       "Debug Link State Update message\n"
 
2002
       "Debug Link State Acknowledgement message\n"
 
2003
       "Debug All message\n"
 
2004
       "Debug only sending message\n"
 
2005
       "Debug only receiving message\n"
 
2006
       );
 
2007
 
 
2008
 
 
2009
DEFUN (no_debug_ospf6_message,
 
2010
       no_debug_ospf6_message_cmd,
 
2011
       "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
 
2012
       NO_STR
 
2013
       DEBUG_STR
 
2014
       OSPF6_STR
 
2015
       "Debug OSPFv3 message\n"
 
2016
       "Debug Unknown message\n"
 
2017
       "Debug Hello message\n"
 
2018
       "Debug Database Description message\n"
 
2019
       "Debug Link State Request message\n"
 
2020
       "Debug Link State Update message\n"
 
2021
       "Debug Link State Acknowledgement message\n"
 
2022
       "Debug All message\n"
 
2023
       )
 
2024
{
 
2025
  unsigned char level = 0;
 
2026
  int type = 0;
 
2027
  int i;
 
2028
 
 
2029
  assert (argc > 0);
 
2030
 
 
2031
  /* check type */
 
2032
  if (! strncmp (argv[0], "u", 1))
 
2033
    type = OSPF6_MESSAGE_TYPE_UNKNOWN;
 
2034
  else if (! strncmp (argv[0], "h", 1))
 
2035
    type = OSPF6_MESSAGE_TYPE_HELLO;
 
2036
  else if (! strncmp (argv[0], "d", 1))
 
2037
    type = OSPF6_MESSAGE_TYPE_DBDESC;
 
2038
  else if (! strncmp (argv[0], "lsr", 3))
 
2039
    type = OSPF6_MESSAGE_TYPE_LSREQ;
 
2040
  else if (! strncmp (argv[0], "lsu", 3))
 
2041
    type = OSPF6_MESSAGE_TYPE_LSUPDATE;
 
2042
  else if (! strncmp (argv[0], "lsa", 3))
 
2043
    type = OSPF6_MESSAGE_TYPE_LSACK;
 
2044
  else if (! strncmp (argv[0], "a", 1))
 
2045
    type = OSPF6_MESSAGE_TYPE_ALL;
 
2046
 
 
2047
  if (argc == 1)
 
2048
    level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
 
2049
  else if (! strncmp (argv[1], "s", 1))
 
2050
    level = OSPF6_DEBUG_MESSAGE_SEND;
 
2051
  else if (! strncmp (argv[1], "r", 1))
 
2052
    level = OSPF6_DEBUG_MESSAGE_RECV;
 
2053
 
 
2054
  if (type == OSPF6_MESSAGE_TYPE_ALL)
 
2055
    {
 
2056
      for (i = 0; i < 6; i++)
 
2057
        OSPF6_DEBUG_MESSAGE_OFF (i, level);
 
2058
    }
 
2059
  else
 
2060
    OSPF6_DEBUG_MESSAGE_OFF (type, level);
 
2061
 
 
2062
  return CMD_SUCCESS;
 
2063
}
 
2064
 
 
2065
ALIAS (no_debug_ospf6_message,
 
2066
       no_debug_ospf6_message_sendrecv_cmd,
 
2067
       "no debug ospf6 message "
 
2068
       "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
 
2069
       NO_STR
 
2070
       DEBUG_STR
 
2071
       OSPF6_STR
 
2072
       "Debug OSPFv3 message\n"
 
2073
       "Debug Unknown message\n"
 
2074
       "Debug Hello message\n"
 
2075
       "Debug Database Description message\n"
 
2076
       "Debug Link State Request message\n"
 
2077
       "Debug Link State Update message\n"
 
2078
       "Debug Link State Acknowledgement message\n"
 
2079
       "Debug All message\n"
 
2080
       "Debug only sending message\n"
 
2081
       "Debug only receiving message\n"
 
2082
       );
 
2083
 
 
2084
int
 
2085
config_write_ospf6_debug_message (struct vty *vty)
 
2086
{
 
2087
  const char *type_str[] = {"unknown", "hello", "dbdesc",
 
2088
                      "lsreq", "lsupdate", "lsack"};
 
2089
  unsigned char s = 0, r = 0;
 
2090
  int i;
 
2091
 
 
2092
  for (i = 0; i < 6; i++)
 
2093
    {
 
2094
      if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
 
2095
        s |= 1 << i;
 
2096
      if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
 
2097
        r |= 1 << i;
 
2098
    }
 
2099
 
 
2100
  if (s == 0x3f && r == 0x3f)
 
2101
    {
 
2102
      vty_out (vty, "debug ospf6 message all%s", VNL);
 
2103
      return 0;
 
2104
    }
 
2105
 
 
2106
  if (s == 0x3f && r == 0)
 
2107
    {
 
2108
      vty_out (vty, "debug ospf6 message all send%s", VNL);
 
2109
      return 0;
 
2110
    }
 
2111
  else if (s == 0 && r == 0x3f)
 
2112
    {
 
2113
      vty_out (vty, "debug ospf6 message all recv%s", VNL);
 
2114
      return 0;
 
2115
    }
 
2116
 
 
2117
  /* Unknown message is logged by default */
 
2118
  if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) &&
 
2119
      ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
 
2120
    vty_out (vty, "no debug ospf6 message unknown%s", VNL);
 
2121
  else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
 
2122
    vty_out (vty, "no debug ospf6 message unknown send%s", VNL);
 
2123
  else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
 
2124
    vty_out (vty, "no debug ospf6 message unknown recv%s", VNL);
 
2125
 
 
2126
  for (i = 1; i < 6; i++)
 
2127
    {
 
2128
      if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) &&
 
2129
          IS_OSPF6_DEBUG_MESSAGE (i, RECV))
 
2130
        vty_out (vty, "debug ospf6 message %s%s", type_str[i], VNL);
 
2131
      else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
 
2132
        vty_out (vty, "debug ospf6 message %s send%s", type_str[i],
 
2133
                 VNL);
 
2134
      else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
 
2135
        vty_out (vty, "debug ospf6 message %s recv%s", type_str[i],
 
2136
                 VNL);
 
2137
    }
 
2138
 
 
2139
  return 0;
 
2140
}
 
2141
 
 
2142
void
 
2143
install_element_ospf6_debug_message ()
 
2144
{
 
2145
  install_element (ENABLE_NODE, &debug_ospf6_message_cmd);
 
2146
  install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd);
 
2147
  install_element (ENABLE_NODE, &debug_ospf6_message_sendrecv_cmd);
 
2148
  install_element (ENABLE_NODE, &no_debug_ospf6_message_sendrecv_cmd);
 
2149
  install_element (CONFIG_NODE, &debug_ospf6_message_cmd);
 
2150
  install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd);
 
2151
  install_element (CONFIG_NODE, &debug_ospf6_message_sendrecv_cmd);
 
2152
  install_element (CONFIG_NODE, &no_debug_ospf6_message_sendrecv_cmd);
 
2153
}
 
2154
 
 
2155