]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - ospf6d/ospf6_message.c
New upstream release and new maintainer
[quagga-debian.git] / ospf6d / ospf6_message.c
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 /* for structures and macros ospf6_lsa_examin() needs */
43 #include "ospf6_abr.h"
44 #include "ospf6_asbr.h"
45 #include "ospf6_intra.h"
46
47 #include "ospf6_flood.h"
48 #include "ospf6d.h"
49
50 #include <netinet/ip6.h>
51
52 unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
53 static const struct message ospf6_message_type_str [] =
54 {
55   { OSPF6_MESSAGE_TYPE_HELLO,    "Hello"    },
56   { OSPF6_MESSAGE_TYPE_DBDESC,   "DbDesc"   },
57   { OSPF6_MESSAGE_TYPE_LSREQ,    "LSReq"    },
58   { OSPF6_MESSAGE_TYPE_LSUPDATE, "LSUpdate" },
59   { OSPF6_MESSAGE_TYPE_LSACK,    "LSAck"    },
60 };
61 static const size_t ospf6_message_type_str_max = array_size(ospf6_message_type_str);
62
63 /* Minimum (besides the standard OSPF packet header) lengths for OSPF
64    packets of particular types, offset is the "type" field. */
65 const u_int16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] =
66 {
67   0,
68   OSPF6_HELLO_MIN_SIZE,
69   OSPF6_DB_DESC_MIN_SIZE,
70   OSPF6_LS_REQ_MIN_SIZE,
71   OSPF6_LS_UPD_MIN_SIZE,
72   OSPF6_LS_ACK_MIN_SIZE
73 };
74
75 /* Minimum (besides the standard LSA header) lengths for LSAs of particular
76    types, offset is the "LSA function code" portion of "LSA type" field. */
77 const u_int16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] =
78 {
79   0,
80   /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE,
81   /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE,
82   /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
83   /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE,
84   /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
85   /* 0x2006 */ 0,
86   /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
87   /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE,
88   /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
89 };
90
91 /* print functions */
92
93 static void
94 ospf6_header_print (struct ospf6_header *oh)
95 {
96   char router_id[16], area_id[16];
97   inet_ntop (AF_INET, &oh->router_id, router_id, sizeof (router_id));
98   inet_ntop (AF_INET, &oh->area_id, area_id, sizeof (area_id));
99
100   zlog_debug ("    OSPFv%d Type:%d Len:%hu Router-ID:%s",
101              oh->version, oh->type, ntohs (oh->length), router_id);
102   zlog_debug ("    Area-ID:%s Cksum:%hx Instance-ID:%d",
103              area_id, ntohs (oh->checksum), oh->instance_id);
104 }
105
106 void
107 ospf6_hello_print (struct ospf6_header *oh)
108 {
109   struct ospf6_hello *hello;
110   char options[16];
111   char drouter[16], bdrouter[16], neighbor[16];
112   char *p;
113
114   ospf6_header_print (oh);
115   assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO);
116
117   hello = (struct ospf6_hello *)
118     ((caddr_t) oh + sizeof (struct ospf6_header));
119
120   inet_ntop (AF_INET, &hello->drouter, drouter, sizeof (drouter));
121   inet_ntop (AF_INET, &hello->bdrouter, bdrouter, sizeof (bdrouter));
122   ospf6_options_printbuf (hello->options, options, sizeof (options));
123
124   zlog_debug ("    I/F-Id:%ld Priority:%d Option:%s",
125              (u_long) ntohl (hello->interface_id), hello->priority, options);
126   zlog_debug ("    HelloInterval:%hu DeadInterval:%hu",
127              ntohs (hello->hello_interval), ntohs (hello->dead_interval));
128   zlog_debug ("    DR:%s BDR:%s", drouter, bdrouter);
129
130   for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
131        p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
132        p += sizeof (u_int32_t))
133     {
134       inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor));
135       zlog_debug ("    Neighbor: %s", neighbor);
136     }
137
138   assert (p == OSPF6_MESSAGE_END (oh));
139 }
140
141 void
142 ospf6_dbdesc_print (struct ospf6_header *oh)
143 {
144   struct ospf6_dbdesc *dbdesc;
145   char options[16];
146   char *p;
147
148   ospf6_header_print (oh);
149   assert (oh->type == OSPF6_MESSAGE_TYPE_DBDESC);
150
151   dbdesc = (struct ospf6_dbdesc *)
152     ((caddr_t) oh + sizeof (struct ospf6_header));
153
154   ospf6_options_printbuf (dbdesc->options, options, sizeof (options));
155
156   zlog_debug ("    MBZ: %#x Option: %s IfMTU: %hu",
157              dbdesc->reserved1, options, ntohs (dbdesc->ifmtu));
158   zlog_debug ("    MBZ: %#x Bits: %s%s%s SeqNum: %#lx",
159              dbdesc->reserved2,
160              (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"),
161              (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"),
162              (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"),
163              (u_long) ntohl (dbdesc->seqnum));
164
165   for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
166        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
167        p += sizeof (struct ospf6_lsa_header))
168     ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
169
170   assert (p == OSPF6_MESSAGE_END (oh));
171 }
172
173 void
174 ospf6_lsreq_print (struct ospf6_header *oh)
175 {
176   char id[16], adv_router[16];
177   char *p;
178
179   ospf6_header_print (oh);
180   assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ);
181
182   for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
183        p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
184        p += sizeof (struct ospf6_lsreq_entry))
185     {
186       struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *) p;
187       inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router));
188       inet_ntop (AF_INET, &e->id, id, sizeof (id));
189       zlog_debug ("    [%s Id:%s Adv:%s]",
190                  ospf6_lstype_name (e->type), id, adv_router);
191     }
192
193   assert (p == OSPF6_MESSAGE_END (oh));
194 }
195
196 void
197 ospf6_lsupdate_print (struct ospf6_header *oh)
198 {
199   struct ospf6_lsupdate *lsupdate;
200   u_long num;
201   char *p;
202
203   ospf6_header_print (oh);
204   assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE);
205
206   lsupdate = (struct ospf6_lsupdate *)
207     ((caddr_t) oh + sizeof (struct ospf6_header));
208
209   num = ntohl (lsupdate->lsa_number);
210   zlog_debug ("    Number of LSA: %ld", num);
211
212   for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
213        p < OSPF6_MESSAGE_END (oh) &&
214        p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
215        p += OSPF6_LSA_SIZE (p))
216     {
217       ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
218     }
219
220   assert (p == OSPF6_MESSAGE_END (oh));
221 }
222
223 void
224 ospf6_lsack_print (struct ospf6_header *oh)
225 {
226   char *p;
227
228   ospf6_header_print (oh);
229   assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
230
231   for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
232        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
233        p += sizeof (struct ospf6_lsa_header))
234     ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
235
236   assert (p == OSPF6_MESSAGE_END (oh));
237 }
238
239 static void
240 ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst,
241                   struct ospf6_interface *oi, struct ospf6_header *oh)
242 {
243   struct ospf6_hello *hello;
244   struct ospf6_neighbor *on;
245   char *p;
246   int twoway = 0;
247   int neighborchange = 0;
248   int backupseen = 0;
249
250   hello = (struct ospf6_hello *)
251     ((caddr_t) oh + sizeof (struct ospf6_header));
252
253   /* HelloInterval check */
254   if (ntohs (hello->hello_interval) != oi->hello_interval)
255     {
256       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
257         zlog_debug ("HelloInterval mismatch");
258       return;
259     }
260
261   /* RouterDeadInterval check */
262   if (ntohs (hello->dead_interval) != oi->dead_interval)
263     {
264       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
265         zlog_debug ("RouterDeadInterval mismatch");
266       return;
267     }
268
269   /* E-bit check */
270   if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) !=
271       OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E))
272     {
273       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
274         zlog_debug ("E-bit mismatch");
275       return;
276     }
277
278   /* Find neighbor, create if not exist */
279   on = ospf6_neighbor_lookup (oh->router_id, oi);
280   if (on == NULL)
281     {
282       on = ospf6_neighbor_create (oh->router_id, oi);
283       on->prev_drouter = on->drouter = hello->drouter;
284       on->prev_bdrouter = on->bdrouter = hello->bdrouter;
285       on->priority = hello->priority;
286     }
287
288   /* always override neighbor's source address and ifindex */
289   on->ifindex = ntohl (hello->interface_id);
290   memcpy (&on->linklocal_addr, src, sizeof (struct in6_addr));
291
292   /* TwoWay check */
293   for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
294        p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
295        p += sizeof (u_int32_t))
296     {
297       u_int32_t *router_id = (u_int32_t *) p;
298
299       if (*router_id == oi->area->ospf6->router_id)
300         twoway++;
301     }
302
303   assert (p == OSPF6_MESSAGE_END (oh));
304
305   /* RouterPriority check */
306   if (on->priority != hello->priority)
307     {
308       on->priority = hello->priority;
309       neighborchange++;
310     }
311
312   /* DR check */
313   if (on->drouter != hello->drouter)
314     {
315       on->prev_drouter = on->drouter;
316       on->drouter = hello->drouter;
317       if (on->prev_drouter == on->router_id || on->drouter == on->router_id)
318         neighborchange++;
319     }
320
321   /* BDR check */
322   if (on->bdrouter != hello->bdrouter)
323     {
324       on->prev_bdrouter = on->bdrouter;
325       on->bdrouter = hello->bdrouter;
326       if (on->prev_bdrouter == on->router_id || on->bdrouter == on->router_id)
327         neighborchange++;
328     }
329
330   /* BackupSeen check */
331   if (oi->state == OSPF6_INTERFACE_WAITING)
332     {
333       if (hello->bdrouter == on->router_id)
334         backupseen++;
335       else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0))
336         backupseen++;
337     }
338
339   /* Execute neighbor events */
340   thread_execute (master, hello_received, on, 0);
341   if (twoway)
342     thread_execute (master, twoway_received, on, 0);
343   else
344     thread_execute (master, oneway_received, on, 0);
345
346   /* Schedule interface events */
347   if (backupseen)
348     thread_add_event (master, backup_seen, oi, 0);
349   if (neighborchange)
350     thread_add_event (master, neighbor_change, oi, 0);
351 }
352
353 static void
354 ospf6_dbdesc_recv_master (struct ospf6_header *oh,
355                           struct ospf6_neighbor *on)
356 {
357   struct ospf6_dbdesc *dbdesc;
358   char *p;
359
360   dbdesc = (struct ospf6_dbdesc *)
361     ((caddr_t) oh + sizeof (struct ospf6_header));
362
363   if (on->state < OSPF6_NEIGHBOR_INIT)
364     {
365       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
366         zlog_debug ("Neighbor state less than Init, ignore");
367       return;
368     }
369
370   switch (on->state)
371     {
372     case OSPF6_NEIGHBOR_TWOWAY:
373       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
374         zlog_debug ("Neighbor state is 2-Way, ignore");
375       return;
376
377     case OSPF6_NEIGHBOR_INIT:
378       thread_execute (master, twoway_received, on, 0);
379       if (on->state != OSPF6_NEIGHBOR_EXSTART)
380         {
381           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
382             zlog_debug ("Neighbor state is not ExStart, ignore");
383           return;
384         }
385       /* else fall through to ExStart */
386
387     case OSPF6_NEIGHBOR_EXSTART:
388       /* if neighbor obeys us as our slave, schedule negotiation_done
389          and process LSA Headers. Otherwise, ignore this message */
390       if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
391           ! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
392           ntohl (dbdesc->seqnum) == on->dbdesc_seqnum)
393         {
394           /* execute NegotiationDone */
395           thread_execute (master, negotiation_done, on, 0);
396
397           /* Record neighbor options */
398           memcpy (on->options, dbdesc->options, sizeof (on->options));
399         }
400       else
401         {
402           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
403             zlog_debug ("Negotiation failed");
404           return;
405         }
406       /* fall through to exchange */
407
408     case OSPF6_NEIGHBOR_EXCHANGE:
409       if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
410         {
411           /* Duplicated DatabaseDescription is dropped by master */
412           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
413             zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
414           return;
415         }
416
417       if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
418         {
419           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
420             zlog_debug ("Master/Slave bit mismatch");
421           thread_add_event (master, seqnumber_mismatch, on, 0);
422           return;
423         }
424
425       if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
426         {
427           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
428             zlog_debug ("Initialize bit mismatch");
429           thread_add_event (master, seqnumber_mismatch, on, 0);
430           return;
431         }
432
433       if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
434         {
435           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
436             zlog_debug ("Option field mismatch");
437           thread_add_event (master, seqnumber_mismatch, on, 0);
438           return;
439         }
440
441       if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum)
442         {
443           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
444             zlog_debug ("Sequence number mismatch (%#lx expected)",
445                        (u_long) on->dbdesc_seqnum);
446           thread_add_event (master, seqnumber_mismatch, on, 0);
447           return;
448         }
449       break;
450
451     case OSPF6_NEIGHBOR_LOADING:
452     case OSPF6_NEIGHBOR_FULL:
453       if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
454         {
455           /* Duplicated DatabaseDescription is dropped by master */
456           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
457             zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
458           return;
459         }
460
461       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
462         zlog_debug ("Not duplicate dbdesc in state %s",
463                     ospf6_neighbor_state_str[on->state]);
464       thread_add_event (master, seqnumber_mismatch, on, 0);
465       return;
466
467     default:
468       assert (0);
469       break;
470     }
471
472   /* Process LSA headers */
473   for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
474        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
475        p += sizeof (struct ospf6_lsa_header))
476     {
477       struct ospf6_lsa *his, *mine;
478       struct ospf6_lsdb *lsdb = NULL;
479
480       his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
481
482       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
483         zlog_debug ("%s", his->name);
484
485       switch (OSPF6_LSA_SCOPE (his->header->type))
486         {
487         case OSPF6_SCOPE_LINKLOCAL:
488           lsdb = on->ospf6_if->lsdb;
489           break;
490         case OSPF6_SCOPE_AREA:
491           lsdb = on->ospf6_if->area->lsdb;
492           break;
493         case OSPF6_SCOPE_AS:
494           lsdb = on->ospf6_if->area->ospf6->lsdb;
495           break;
496         case OSPF6_SCOPE_RESERVED:
497           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
498             zlog_debug ("Ignoring LSA of reserved scope");
499           ospf6_lsa_delete (his);
500           continue;
501           break;
502         }
503
504       if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
505           IS_AREA_STUB (on->ospf6_if->area))
506         {
507           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
508             zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
509           ospf6_lsa_delete (his);
510           thread_add_event (master, seqnumber_mismatch, on, 0);
511           return;
512         }
513
514       mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
515                                 his->header->adv_router, lsdb);
516       if (mine == NULL)
517         {
518           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
519             zlog_debug ("Add request (No database copy)");
520           ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
521         }
522       else if (ospf6_lsa_compare (his, mine) < 0)
523         {
524           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
525             zlog_debug ("Add request (Received MoreRecent)");
526           ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
527         }
528       else
529         {
530           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
531             zlog_debug ("Discard (Existing MoreRecent)");
532         }
533       ospf6_lsa_delete (his);
534     }
535
536   assert (p == OSPF6_MESSAGE_END (oh));
537
538   /* Increment sequence number */
539   on->dbdesc_seqnum ++;
540
541   /* schedule send lsreq */
542   if (on->request_list->count && (on->thread_send_lsreq == NULL))
543     on->thread_send_lsreq =
544       thread_add_event (master, ospf6_lsreq_send, on, 0);
545
546   THREAD_OFF (on->thread_send_dbdesc);
547
548   /* More bit check */
549   if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
550       ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
551     thread_add_event (master, exchange_done, on, 0);
552   else
553     on->thread_send_dbdesc =
554       thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
555
556   /* save last received dbdesc */
557   memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
558 }
559
560 static void
561 ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
562                          struct ospf6_neighbor *on)
563 {
564   struct ospf6_dbdesc *dbdesc;
565   char *p;
566
567   dbdesc = (struct ospf6_dbdesc *)
568     ((caddr_t) oh + sizeof (struct ospf6_header));
569
570   if (on->state < OSPF6_NEIGHBOR_INIT)
571     {
572       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
573         zlog_debug ("Neighbor state less than Init, ignore");
574       return;
575     }
576
577   switch (on->state)
578     {
579     case OSPF6_NEIGHBOR_TWOWAY:
580       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
581         zlog_debug ("Neighbor state is 2-Way, ignore");
582       return;
583
584     case OSPF6_NEIGHBOR_INIT:
585       thread_execute (master, twoway_received, on, 0);
586       if (on->state != OSPF6_NEIGHBOR_EXSTART)
587         {
588           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
589             zlog_debug ("Neighbor state is not ExStart, ignore");
590           return;
591         }
592       /* else fall through to ExStart */
593
594     case OSPF6_NEIGHBOR_EXSTART:
595       /* If the neighbor is Master, act as Slave. Schedule negotiation_done
596          and process LSA Headers. Otherwise, ignore this message */
597       if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
598           CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
599           CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
600           ntohs (oh->length) == sizeof (struct ospf6_header) +
601                                 sizeof (struct ospf6_dbdesc))
602         {
603           /* set the master/slave bit to slave */
604           UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
605
606           /* set the DD sequence number to one specified by master */
607           on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
608
609           /* schedule NegotiationDone */
610           thread_execute (master, negotiation_done, on, 0);
611
612           /* Record neighbor options */
613           memcpy (on->options, dbdesc->options, sizeof (on->options));
614         }
615       else
616         {
617           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
618             zlog_debug ("Negotiation failed");
619           return;
620         }
621       break;
622
623     case OSPF6_NEIGHBOR_EXCHANGE:
624       if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
625         {
626           /* Duplicated DatabaseDescription causes slave to retransmit */
627           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
628             zlog_debug ("Duplicated dbdesc causes retransmit");
629           THREAD_OFF (on->thread_send_dbdesc);
630           on->thread_send_dbdesc =
631             thread_add_event (master, ospf6_dbdesc_send, on, 0);
632           return;
633         }
634
635       if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
636         {
637           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
638             zlog_debug ("Master/Slave bit mismatch");
639           thread_add_event (master, seqnumber_mismatch, on, 0);
640           return;
641         }
642
643       if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
644         {
645           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
646             zlog_debug ("Initialize bit mismatch");
647           thread_add_event (master, seqnumber_mismatch, on, 0);
648           return;
649         }
650
651       if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
652         {
653           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
654             zlog_debug ("Option field mismatch");
655           thread_add_event (master, seqnumber_mismatch, on, 0);
656           return;
657         }
658
659       if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum + 1)
660         {
661           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
662             zlog_debug ("Sequence number mismatch (%#lx expected)",
663                         (u_long) on->dbdesc_seqnum + 1);
664           thread_add_event (master, seqnumber_mismatch, on, 0);
665           return;
666         }
667       break;
668
669     case OSPF6_NEIGHBOR_LOADING:
670     case OSPF6_NEIGHBOR_FULL:
671       if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
672         {
673           /* Duplicated DatabaseDescription causes slave to retransmit */
674           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
675             zlog_debug ("Duplicated dbdesc causes retransmit");
676           THREAD_OFF (on->thread_send_dbdesc);
677           on->thread_send_dbdesc =
678             thread_add_event (master, ospf6_dbdesc_send, on, 0);
679           return;
680         }
681
682       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
683         zlog_debug ("Not duplicate dbdesc in state %s",
684                     ospf6_neighbor_state_str[on->state]);
685       thread_add_event (master, seqnumber_mismatch, on, 0);
686       return;
687
688     default:
689       assert (0);
690       break;
691     }
692
693   /* Process LSA headers */
694   for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
695        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
696        p += sizeof (struct ospf6_lsa_header))
697     {
698       struct ospf6_lsa *his, *mine;
699       struct ospf6_lsdb *lsdb = NULL;
700
701       his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
702
703       switch (OSPF6_LSA_SCOPE (his->header->type))
704         {
705         case OSPF6_SCOPE_LINKLOCAL:
706           lsdb = on->ospf6_if->lsdb;
707           break;
708         case OSPF6_SCOPE_AREA:
709           lsdb = on->ospf6_if->area->lsdb;
710           break;
711         case OSPF6_SCOPE_AS:
712           lsdb = on->ospf6_if->area->ospf6->lsdb;
713           break;
714         case OSPF6_SCOPE_RESERVED:
715           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
716             zlog_debug ("Ignoring LSA of reserved scope");
717           ospf6_lsa_delete (his);
718           continue;
719           break;
720         }
721
722       if (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS &&
723           IS_AREA_STUB (on->ospf6_if->area))
724         {
725           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
726             zlog_debug ("E-bit mismatch with LSA Headers");
727           ospf6_lsa_delete (his);
728           thread_add_event (master, seqnumber_mismatch, on, 0);
729           return;
730         }
731
732       mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
733                                 his->header->adv_router, lsdb);
734       if (mine == NULL || ospf6_lsa_compare (his, mine) < 0)
735         {
736           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
737             zlog_debug ("Add request-list: %s", his->name);
738           ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
739         }
740       ospf6_lsa_delete (his);
741     }
742
743   assert (p == OSPF6_MESSAGE_END (oh));
744
745   /* Set sequence number to Master's */
746   on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
747
748   /* schedule send lsreq */
749   if ((on->thread_send_lsreq == NULL) &&
750       (on->request_list->count))
751     on->thread_send_lsreq =
752       thread_add_event (master, ospf6_lsreq_send, on, 0);
753
754   THREAD_OFF (on->thread_send_dbdesc);
755   on->thread_send_dbdesc =
756     thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
757
758   /* save last received dbdesc */
759   memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
760 }
761
762 static void
763 ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst,
764                    struct ospf6_interface *oi, struct ospf6_header *oh)
765 {
766   struct ospf6_neighbor *on;
767   struct ospf6_dbdesc *dbdesc;
768
769   on = ospf6_neighbor_lookup (oh->router_id, oi);
770   if (on == NULL)
771     {
772       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
773         zlog_debug ("Neighbor not found, ignore");
774       return;
775     }
776
777   dbdesc = (struct ospf6_dbdesc *)
778     ((caddr_t) oh + sizeof (struct ospf6_header));
779
780   /* Interface MTU check */
781   if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu)
782     {
783       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
784         zlog_debug ("I/F MTU mismatch");
785       return;
786     }
787
788   if (dbdesc->reserved1 || dbdesc->reserved2)
789     {
790       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
791         zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
792                     on->name);
793       dbdesc->reserved1 = 0;
794       dbdesc->reserved2 = 0;
795     }
796
797   if (ntohl (oh->router_id) < ntohl (ospf6->router_id))
798     ospf6_dbdesc_recv_master (oh, on);
799   else if (ntohl (ospf6->router_id) < ntohl (oh->router_id))
800     ospf6_dbdesc_recv_slave (oh, on);
801   else
802     {
803       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
804         zlog_debug ("Can't decide which is master, ignore");
805     }
806 }
807
808 static void
809 ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
810                   struct ospf6_interface *oi, struct ospf6_header *oh)
811 {
812   struct ospf6_neighbor *on;
813   char *p;
814   struct ospf6_lsreq_entry *e;
815   struct ospf6_lsdb *lsdb = NULL;
816   struct ospf6_lsa *lsa;
817
818   on = ospf6_neighbor_lookup (oh->router_id, oi);
819   if (on == NULL)
820     {
821       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
822         zlog_debug ("Neighbor not found, ignore");
823       return;
824     }
825
826   if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
827       on->state != OSPF6_NEIGHBOR_LOADING &&
828       on->state != OSPF6_NEIGHBOR_FULL)
829     {
830       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
831         zlog_debug ("Neighbor state less than Exchange, ignore");
832       return;
833     }
834
835   /* Process each request */
836   for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
837        p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
838        p += sizeof (struct ospf6_lsreq_entry))
839     {
840       e = (struct ospf6_lsreq_entry *) p;
841
842       switch (OSPF6_LSA_SCOPE (e->type))
843         {
844         case OSPF6_SCOPE_LINKLOCAL:
845           lsdb = on->ospf6_if->lsdb;
846           break;
847         case OSPF6_SCOPE_AREA:
848           lsdb = on->ospf6_if->area->lsdb;
849           break;
850         case OSPF6_SCOPE_AS:
851           lsdb = on->ospf6_if->area->ospf6->lsdb;
852           break;
853         default:
854           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
855             zlog_debug ("Ignoring LSA of reserved scope");
856           continue;
857           break;
858         }
859
860       /* Find database copy */
861       lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb);
862       if (lsa == NULL)
863         {
864           char id[16], adv_router[16];
865           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
866             {
867               inet_ntop (AF_INET, &e->id, id, sizeof (id));
868               inet_ntop (AF_INET, &e->adv_router, adv_router,
869                      sizeof (adv_router));
870               zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
871                           ospf6_lstype_name (e->type), id, adv_router);
872             }
873           thread_add_event (master, bad_lsreq, on, 0);
874           return;
875         }
876
877       ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list);
878     }
879
880   assert (p == OSPF6_MESSAGE_END (oh));
881
882   /* schedule send lsupdate */
883   THREAD_OFF (on->thread_send_lsupdate);
884   on->thread_send_lsupdate =
885     thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
886 }
887
888 /* Verify, that the specified memory area contains exactly N valid IPv6
889    prefixes as specified by RFC5340, A.4.1. */
890 static unsigned
891 ospf6_prefixes_examin
892 (
893   struct ospf6_prefix *current, /* start of buffer    */
894   unsigned length,
895   const u_int32_t req_num_pfxs  /* always compared with the actual number of prefixes */
896 )
897 {
898   u_char requested_pfx_bytes;
899   u_int32_t real_num_pfxs = 0;
900
901   while (length)
902   {
903     if (length < OSPF6_PREFIX_MIN_SIZE)
904     {
905       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
906         zlog_debug ("%s: undersized IPv6 prefix header", __func__);
907       return MSG_NG;
908     }
909     /* safe to look deeper */
910     if (current->prefix_length > IPV6_MAX_BITLEN)
911     {
912       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
913         zlog_debug ("%s: invalid PrefixLength (%u bits)", __func__, current->prefix_length);
914       return MSG_NG;
915     }
916     /* covers both fixed- and variable-sized fields */
917     requested_pfx_bytes = OSPF6_PREFIX_MIN_SIZE + OSPF6_PREFIX_SPACE (current->prefix_length);
918     if (requested_pfx_bytes > length)
919     {
920       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
921         zlog_debug ("%s: undersized IPv6 prefix", __func__);
922       return MSG_NG;
923     }
924     /* next prefix */
925     length -= requested_pfx_bytes;
926     current = (struct ospf6_prefix *) ((caddr_t) current + requested_pfx_bytes);
927     real_num_pfxs++;
928   }
929   if (real_num_pfxs != req_num_pfxs)
930   {
931     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
932       zlog_debug ("%s: IPv6 prefix number mismatch (%u required, %u real)",
933                   __func__, req_num_pfxs, real_num_pfxs);
934     return MSG_NG;
935   }
936   return MSG_OK;
937 }
938
939 /* Verify an LSA to have a valid length and dispatch further (where
940    appropriate) to check if the contents, including nested IPv6 prefixes,
941    is properly sized/aligned within the LSA. Note that this function gets
942    LSA type in network byte order, uses in host byte order and passes to
943    ospf6_lstype_name() in network byte order again. */
944 static unsigned
945 ospf6_lsa_examin (struct ospf6_lsa_header *lsah, const u_int16_t lsalen, const u_char headeronly)
946 {
947   struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
948   struct ospf6_as_external_lsa *as_external_lsa;
949   struct ospf6_link_lsa *link_lsa;
950   unsigned exp_length;
951   u_int8_t ltindex;
952   u_int16_t lsatype;
953
954   /* In case an additional minimum length constraint is defined for current
955      LSA type, make sure that this constraint is met. */
956   lsatype = ntohs (lsah->type);
957   ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK;
958   if
959   (
960     ltindex < OSPF6_LSTYPE_SIZE &&
961     ospf6_lsa_minlen[ltindex] &&
962     lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE
963   )
964   {
965     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
966       zlog_debug ("%s: undersized (%u B) LSA", __func__, lsalen);
967     return MSG_NG;
968   }
969   switch (lsatype)
970   {
971   case OSPF6_LSTYPE_ROUTER:
972     /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes followed
973        by N>=0 interface descriptions. */
974     if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE) % OSPF6_ROUTER_LSDESC_FIX_SIZE)
975     {
976       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
977         zlog_debug ("%s: interface description alignment error", __func__);
978       return MSG_NG;
979     }
980     break;
981   case OSPF6_LSTYPE_NETWORK:
982     /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes
983        followed by N>=0 attached router descriptions. */
984     if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_NETWORK_LSA_MIN_SIZE) % OSPF6_NETWORK_LSDESC_FIX_SIZE)
985     {
986       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
987         zlog_debug ("%s: router description alignment error", __func__);
988       return MSG_NG;
989     }
990     break;
991   case OSPF6_LSTYPE_INTER_PREFIX:
992     /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE bytes
993        followed by 3-4 fields of a single IPv6 prefix. */
994     if (headeronly)
995       break;
996     return ospf6_prefixes_examin
997     (
998       (struct ospf6_prefix *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_PREFIX_LSA_MIN_SIZE),
999       lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
1000       1
1001     );
1002   case OSPF6_LSTYPE_INTER_ROUTER:
1003     /* RFC5340 A.4.6, fixed-size LSA. */
1004     if (lsalen > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE)
1005     {
1006       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1007         zlog_debug ("%s: oversized (%u B) LSA", __func__, lsalen);
1008       return MSG_NG;
1009     }
1010     break;
1011   case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */
1012   case OSPF6_LSTYPE_TYPE_7:
1013     /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE bytes
1014        followed by 3-4 fields of IPv6 prefix and 3 conditional LSA fields:
1015        16 bytes of forwarding address, 4 bytes of external route tag,
1016        4 bytes of referenced link state ID. */
1017     if (headeronly)
1018       break;
1019     as_external_lsa = (struct ospf6_as_external_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1020     exp_length = OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE;
1021     /* To find out if the last optional field (Referenced Link State ID) is
1022        assumed in this LSA, we need to access fixed fields of the IPv6
1023        prefix before ospf6_prefix_examin() confirms its sizing. */
1024     if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen)
1025     {
1026       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1027         zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen);
1028       return MSG_NG;
1029     }
1030     /* forwarding address */
1031     if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
1032       exp_length += 16;
1033     /* external route tag */
1034     if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
1035       exp_length += 4;
1036     /* referenced link state ID */
1037     if (as_external_lsa->prefix.u._prefix_referenced_lstype)
1038       exp_length += 4;
1039     /* All the fixed-size fields (mandatory and optional) must fit. I.e.,
1040        this check does not include any IPv6 prefix fields. */
1041     if (exp_length > lsalen)
1042     {
1043       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1044         zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen);
1045       return MSG_NG;
1046     }
1047     /* The last call completely covers the remainder (IPv6 prefix). */
1048     return ospf6_prefixes_examin
1049     (
1050       (struct ospf6_prefix *) ((caddr_t) as_external_lsa + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE),
1051       lsalen - exp_length,
1052       1
1053     );
1054   case OSPF6_LSTYPE_LINK:
1055     /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes followed
1056        by N>=0 IPv6 prefix blocks (with N declared beforehand). */
1057     if (headeronly)
1058       break;
1059     link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1060     return ospf6_prefixes_examin
1061     (
1062       (struct ospf6_prefix *) ((caddr_t) link_lsa + OSPF6_LINK_LSA_MIN_SIZE),
1063       lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_LINK_LSA_MIN_SIZE,
1064       ntohl (link_lsa->prefix_num) /* 32 bits */
1065     );
1066   case OSPF6_LSTYPE_INTRA_PREFIX:
1067   /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE bytes
1068      followed by N>=0 IPv6 prefixes (with N declared beforehand). */
1069     if (headeronly)
1070       break;
1071     intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1072     return ospf6_prefixes_examin
1073     (
1074       (struct ospf6_prefix *) ((caddr_t) intra_prefix_lsa + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE),
1075       lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE,
1076       ntohs (intra_prefix_lsa->prefix_num) /* 16 bits */
1077     );
1078   }
1079   /* No additional validation is possible for unknown LSA types, which are
1080      themselves valid in OPSFv3, hence the default decision is to accept. */
1081   return MSG_OK;
1082 }
1083
1084 /* Verify if the provided input buffer is a valid sequence of LSAs. This
1085    includes verification of LSA blocks length/alignment and dispatching
1086    of deeper-level checks. */
1087 static unsigned
1088 ospf6_lsaseq_examin
1089 (
1090   struct ospf6_lsa_header *lsah, /* start of buffered data */
1091   size_t length,
1092   const u_char headeronly,
1093   /* When declared_num_lsas is not 0, compare it to the real number of LSAs
1094      and treat the difference as an error. */
1095   const u_int32_t declared_num_lsas
1096 )
1097 {
1098   u_int32_t counted_lsas = 0;
1099
1100   while (length)
1101   {
1102     u_int16_t lsalen;
1103     if (length < OSPF6_LSA_HEADER_SIZE)
1104     {
1105       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1106         zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
1107                     __func__, length, counted_lsas);
1108       return MSG_NG;
1109     }
1110     /* save on ntohs() calls here and in the LSA validator */
1111     lsalen = OSPF6_LSA_SIZE (lsah);
1112     if (lsalen < OSPF6_LSA_HEADER_SIZE)
1113     {
1114       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1115         zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
1116                     __func__, counted_lsas, lsalen);
1117       return MSG_NG;
1118     }
1119     if (headeronly)
1120     {
1121       /* less checks here and in ospf6_lsa_examin() */
1122       if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 1))
1123       {
1124         if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1125           zlog_debug ("%s: anomaly in header-only %s LSA #%u", __func__,
1126                       ospf6_lstype_name (lsah->type), counted_lsas);
1127         return MSG_NG;
1128       }
1129       lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1130       length -= OSPF6_LSA_HEADER_SIZE;
1131     }
1132     else
1133     {
1134       /* make sure the input buffer is deep enough before further checks */
1135       if (lsalen > length)
1136       {
1137         if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1138           zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B",
1139                       __func__, ospf6_lstype_name (lsah->type), counted_lsas, lsalen, length);
1140         return MSG_NG;
1141       }
1142       if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 0))
1143       {
1144         if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1145           zlog_debug ("%s: anomaly in %s LSA #%u", __func__,
1146                       ospf6_lstype_name (lsah->type), counted_lsas);
1147         return MSG_NG;
1148       }
1149       lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + lsalen);
1150       length -= lsalen;
1151     }
1152     counted_lsas++;
1153   }
1154
1155   if (declared_num_lsas && counted_lsas != declared_num_lsas)
1156   {
1157     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1158       zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
1159                   __func__, declared_num_lsas, counted_lsas);
1160     return MSG_NG;
1161   }
1162   return MSG_OK;
1163 }
1164
1165 /* Verify a complete OSPF packet for proper sizing/alignment. */
1166 static unsigned
1167 ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire)
1168 {
1169   struct ospf6_lsupdate *lsupd;
1170   unsigned test;
1171
1172   /* length, 1st approximation */
1173   if (bytesonwire < OSPF6_HEADER_SIZE)
1174   {
1175     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1176       zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
1177     return MSG_NG;
1178   }
1179   /* Now it is safe to access header fields. */
1180   if (bytesonwire != ntohs (oh->length))
1181   {
1182     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1183       zlog_debug ("%s: packet length error (%u real, %u declared)",
1184                   __func__, bytesonwire, ntohs (oh->length));
1185     return MSG_NG;
1186   }
1187   /* version check */
1188   if (oh->version != OSPFV3_VERSION)
1189   {
1190     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1191       zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
1192     return MSG_NG;
1193   }
1194   /* length, 2nd approximation */
1195   if
1196   (
1197     oh->type < OSPF6_MESSAGE_TYPE_ALL &&
1198     ospf6_packet_minlen[oh->type] &&
1199     bytesonwire < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type]
1200   )
1201   {
1202     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1203       zlog_debug ("%s: undersized (%u B) %s packet", __func__,
1204                   bytesonwire, LOOKUP (ospf6_message_type_str, oh->type));
1205     return MSG_NG;
1206   }
1207   /* type-specific deeper validation */
1208   switch (oh->type)
1209   {
1210   case OSPF6_MESSAGE_TYPE_HELLO:
1211     /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes followed
1212        by N>=0 router-IDs. */
1213     if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE) % 4)
1214       return MSG_OK;
1215     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1216       zlog_debug ("%s: alignment error in %s packet",
1217                   __func__, LOOKUP (ospf6_message_type_str, oh->type));
1218     return MSG_NG;
1219   case OSPF6_MESSAGE_TYPE_DBDESC:
1220     /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes followed
1221        by N>=0 header-only LSAs. */
1222     test = ospf6_lsaseq_examin
1223     (
1224       (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_DB_DESC_MIN_SIZE),
1225       bytesonwire - OSPF6_HEADER_SIZE - OSPF6_DB_DESC_MIN_SIZE,
1226       1,
1227       0
1228     );
1229     break;
1230   case OSPF6_MESSAGE_TYPE_LSREQ:
1231     /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */
1232     if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE) % OSPF6_LSREQ_LSDESC_FIX_SIZE)
1233       return MSG_OK;
1234     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1235       zlog_debug ("%s: alignment error in %s packet",
1236                   __func__, LOOKUP (ospf6_message_type_str, oh->type));
1237     return MSG_NG;
1238   case OSPF6_MESSAGE_TYPE_LSUPDATE:
1239     /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes followed
1240        by N>=0 full LSAs (with N declared beforehand). */
1241     lsupd = (struct ospf6_lsupdate *) ((caddr_t) oh + OSPF6_HEADER_SIZE);
1242     test = ospf6_lsaseq_examin
1243     (
1244       (struct ospf6_lsa_header *) ((caddr_t) lsupd + OSPF6_LS_UPD_MIN_SIZE),
1245       bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE,
1246       0,
1247       ntohl (lsupd->lsa_number) /* 32 bits */
1248     );
1249     break;
1250   case OSPF6_MESSAGE_TYPE_LSACK:
1251     /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */
1252     test = ospf6_lsaseq_examin
1253     (
1254       (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_LS_ACK_MIN_SIZE),
1255       bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE,
1256       1,
1257       0
1258     );
1259     break;
1260   default:
1261     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1262       zlog_debug ("%s: invalid (%u) message type", __func__, oh->type);
1263     return MSG_NG;
1264   }
1265   if (test != MSG_OK && IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1266     zlog_debug ("%s: anomaly in %s packet", __func__, LOOKUP (ospf6_message_type_str, oh->type));
1267   return test;
1268 }
1269
1270 /* Verify particular fields of otherwise correct received OSPF packet to
1271    meet the requirements of RFC. */
1272 static int
1273 ospf6_rxpacket_examin (struct ospf6_interface *oi, struct ospf6_header *oh, const unsigned bytesonwire)
1274 {
1275   char buf[2][INET_ADDRSTRLEN];
1276
1277   if (MSG_OK != ospf6_packet_examin (oh, bytesonwire))
1278     return MSG_NG;
1279
1280   /* Area-ID check */
1281   if (oh->area_id != oi->area->area_id)
1282   {
1283     if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1284     {
1285       if (oh->area_id == OSPF_AREA_BACKBONE)
1286         zlog_debug ("%s: Message may be via Virtual Link: not supported", __func__);
1287       else
1288         zlog_debug
1289         (
1290           "%s: Area-ID mismatch (my %s, rcvd %s)", __func__,
1291           inet_ntop (AF_INET, &oi->area->area_id, buf[0], INET_ADDRSTRLEN),
1292           inet_ntop (AF_INET, &oh->area_id, buf[1], INET_ADDRSTRLEN)
1293          );
1294     }
1295     return MSG_NG;
1296   }
1297
1298   /* Instance-ID check */
1299   if (oh->instance_id != oi->instance_id)
1300   {
1301     if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1302       zlog_debug ("%s: Instance-ID mismatch (my %u, rcvd %u)", __func__, oi->instance_id, oh->instance_id);
1303     return MSG_NG;
1304   }
1305
1306   /* Router-ID check */
1307   if (oh->router_id == oi->area->ospf6->router_id)
1308   {
1309     zlog_warn ("%s: Duplicate Router-ID (%s)", __func__, inet_ntop (AF_INET, &oh->router_id, buf[0], INET_ADDRSTRLEN));
1310     return MSG_NG;
1311   }
1312   return MSG_OK;
1313 }
1314
1315 static void
1316 ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst,
1317                      struct ospf6_interface *oi, struct ospf6_header *oh)
1318 {
1319   struct ospf6_neighbor *on;
1320   struct ospf6_lsupdate *lsupdate;
1321   char *p;
1322
1323   on = ospf6_neighbor_lookup (oh->router_id, oi);
1324   if (on == NULL)
1325     {
1326       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1327         zlog_debug ("Neighbor not found, ignore");
1328       return;
1329     }
1330
1331   if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1332       on->state != OSPF6_NEIGHBOR_LOADING &&
1333       on->state != OSPF6_NEIGHBOR_FULL)
1334     {
1335       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1336         zlog_debug ("Neighbor state less than Exchange, ignore");
1337       return;
1338     }
1339
1340   lsupdate = (struct ospf6_lsupdate *)
1341     ((caddr_t) oh + sizeof (struct ospf6_header));
1342
1343   /* Process LSAs */
1344   for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
1345        p < OSPF6_MESSAGE_END (oh) &&
1346        p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
1347        p += OSPF6_LSA_SIZE (p))
1348     {
1349       ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p);
1350     }
1351
1352   assert (p == OSPF6_MESSAGE_END (oh));
1353
1354 }
1355
1356 static void
1357 ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst,
1358                   struct ospf6_interface *oi, struct ospf6_header *oh)
1359 {
1360   struct ospf6_neighbor *on;
1361   char *p;
1362   struct ospf6_lsa *his, *mine;
1363   struct ospf6_lsdb *lsdb = NULL;
1364
1365   assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
1366
1367   on = ospf6_neighbor_lookup (oh->router_id, oi);
1368   if (on == NULL)
1369     {
1370       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1371         zlog_debug ("Neighbor not found, ignore");
1372       return;
1373     }
1374
1375   if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1376       on->state != OSPF6_NEIGHBOR_LOADING &&
1377       on->state != OSPF6_NEIGHBOR_FULL)
1378     {
1379       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1380         zlog_debug ("Neighbor state less than Exchange, ignore");
1381       return;
1382     }
1383
1384   for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
1385        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
1386        p += sizeof (struct ospf6_lsa_header))
1387     {
1388       his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
1389
1390       switch (OSPF6_LSA_SCOPE (his->header->type))
1391         {
1392         case OSPF6_SCOPE_LINKLOCAL:
1393           lsdb = on->ospf6_if->lsdb;
1394           break;
1395         case OSPF6_SCOPE_AREA:
1396           lsdb = on->ospf6_if->area->lsdb;
1397           break;
1398         case OSPF6_SCOPE_AS:
1399           lsdb = on->ospf6_if->area->ospf6->lsdb;
1400           break;
1401         case OSPF6_SCOPE_RESERVED:
1402           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1403             zlog_debug ("Ignoring LSA of reserved scope");
1404           ospf6_lsa_delete (his);
1405           continue;
1406           break;
1407         }
1408
1409       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1410         zlog_debug ("%s acknowledged by %s", his->name, on->name);
1411
1412       /* Find database copy */
1413       mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
1414                                 his->header->adv_router, lsdb);
1415       if (mine == NULL)
1416         {
1417           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1418             zlog_debug ("No database copy");
1419           ospf6_lsa_delete (his);
1420           continue;
1421         }
1422
1423       /* Check if the LSA is on his retrans-list */
1424       mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
1425                                 his->header->adv_router, on->retrans_list);
1426       if (mine == NULL)
1427         {
1428           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1429             zlog_debug ("Not on %s's retrans-list", on->name);
1430           ospf6_lsa_delete (his);
1431           continue;
1432         }
1433
1434       if (ospf6_lsa_compare (his, mine) != 0)
1435         {
1436           /* Log this questionable acknowledgement,
1437              and examine the next one. */
1438           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1439             zlog_debug ("Questionable acknowledgement");
1440           ospf6_lsa_delete (his);
1441           continue;
1442         }
1443
1444       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1445         zlog_debug ("Acknowledged, remove from %s's retrans-list",
1446                     on->name);
1447
1448       ospf6_decrement_retrans_count (mine);
1449       if (OSPF6_LSA_IS_MAXAGE (mine))
1450         ospf6_maxage_remove (on->ospf6_if->area->ospf6);
1451       ospf6_lsdb_remove (mine, on->retrans_list);
1452       ospf6_lsa_delete (his);
1453     }
1454
1455   assert (p == OSPF6_MESSAGE_END (oh));
1456 }
1457
1458 static u_char *recvbuf = NULL;
1459 static u_char *sendbuf = NULL;
1460 static unsigned int iobuflen = 0;
1461
1462 int
1463 ospf6_iobuf_size (unsigned int size)
1464 {
1465   u_char *recvnew, *sendnew;
1466
1467   if (size <= iobuflen)
1468     return iobuflen;
1469
1470   recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1471   sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1472   if (recvnew == NULL || sendnew == NULL)
1473     {
1474       if (recvnew)
1475         XFREE (MTYPE_OSPF6_MESSAGE, recvnew);
1476       if (sendnew)
1477         XFREE (MTYPE_OSPF6_MESSAGE, sendnew);
1478       zlog_debug ("Could not allocate I/O buffer of size %d.", size);
1479       return iobuflen;
1480     }
1481
1482   if (recvbuf)
1483     XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
1484   if (sendbuf)
1485     XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
1486   recvbuf = recvnew;
1487   sendbuf = sendnew;
1488   iobuflen = size;
1489
1490   return iobuflen;
1491 }
1492
1493 void
1494 ospf6_message_terminate (void)
1495 {
1496   if (recvbuf)
1497     {
1498       XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
1499       recvbuf = NULL;
1500     }
1501
1502   if (sendbuf)
1503     {
1504       XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
1505       sendbuf = NULL;
1506     }
1507
1508   iobuflen = 0;
1509 }
1510
1511 int
1512 ospf6_receive (struct thread *thread)
1513 {
1514   int sockfd;
1515   unsigned int len;
1516   char srcname[64], dstname[64];
1517   struct in6_addr src, dst;
1518   ifindex_t ifindex;
1519   struct iovec iovector[2];
1520   struct ospf6_interface *oi;
1521   struct ospf6_header *oh;
1522
1523   /* add next read thread */
1524   sockfd = THREAD_FD (thread);
1525   thread_add_read (master, ospf6_receive, NULL, sockfd);
1526
1527   /* initialize */
1528   memset (&src, 0, sizeof (src));
1529   memset (&dst, 0, sizeof (dst));
1530   ifindex = 0;
1531   memset (recvbuf, 0, iobuflen);
1532   iovector[0].iov_base = recvbuf;
1533   iovector[0].iov_len = iobuflen;
1534   iovector[1].iov_base = NULL;
1535   iovector[1].iov_len = 0;
1536
1537   /* receive message */
1538   len = ospf6_recvmsg (&src, &dst, &ifindex, iovector);
1539   if (len > iobuflen)
1540     {
1541       zlog_err ("Excess message read");
1542       return 0;
1543     }
1544
1545   oi = ospf6_interface_lookup_by_ifindex (ifindex);
1546   if (oi == NULL || oi->area == NULL || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
1547     {
1548       zlog_debug ("Message received on disabled interface");
1549       return 0;
1550     }
1551   if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
1552     {
1553       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1554         zlog_debug ("%s: Ignore message on passive interface %s",
1555                     __func__, oi->interface->name);
1556       return 0;
1557     }
1558
1559   oh = (struct ospf6_header *) recvbuf;
1560   if (ospf6_rxpacket_examin (oi, oh, len) != MSG_OK)
1561     return 0;
1562
1563   /* Being here means, that no sizing/alignment issues were detected in
1564      the input packet. This renders the additional checks performed below
1565      and also in the type-specific dispatching functions a dead code,
1566      which can be dismissed in a cleanup-focused review round later. */
1567
1568   /* Log */
1569   if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1570     {
1571       inet_ntop (AF_INET6, &src, srcname, sizeof (srcname));
1572       inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname));
1573       zlog_debug ("%s received on %s",
1574                  LOOKUP (ospf6_message_type_str, oh->type), oi->interface->name);
1575       zlog_debug ("    src: %s", srcname);
1576       zlog_debug ("    dst: %s", dstname);
1577
1578       switch (oh->type)
1579         {
1580           case OSPF6_MESSAGE_TYPE_HELLO:
1581             ospf6_hello_print (oh);
1582             break;
1583           case OSPF6_MESSAGE_TYPE_DBDESC:
1584             ospf6_dbdesc_print (oh);
1585             break;
1586           case OSPF6_MESSAGE_TYPE_LSREQ:
1587             ospf6_lsreq_print (oh);
1588             break;
1589           case OSPF6_MESSAGE_TYPE_LSUPDATE:
1590             ospf6_lsupdate_print (oh);
1591             break;
1592           case OSPF6_MESSAGE_TYPE_LSACK:
1593             ospf6_lsack_print (oh);
1594             break;
1595           default:
1596             assert (0);
1597         }
1598     }
1599
1600   switch (oh->type)
1601     {
1602       case OSPF6_MESSAGE_TYPE_HELLO:
1603         ospf6_hello_recv (&src, &dst, oi, oh);
1604         break;
1605
1606       case OSPF6_MESSAGE_TYPE_DBDESC:
1607         ospf6_dbdesc_recv (&src, &dst, oi, oh);
1608         break;
1609
1610       case OSPF6_MESSAGE_TYPE_LSREQ:
1611         ospf6_lsreq_recv (&src, &dst, oi, oh);
1612         break;
1613
1614       case OSPF6_MESSAGE_TYPE_LSUPDATE:
1615         ospf6_lsupdate_recv (&src, &dst, oi, oh);
1616         break;
1617
1618       case OSPF6_MESSAGE_TYPE_LSACK:
1619         ospf6_lsack_recv (&src, &dst, oi, oh);
1620         break;
1621
1622       default:
1623         assert (0);
1624     }
1625
1626   return 0;
1627 }
1628
1629 static void
1630 ospf6_send (struct in6_addr *src, struct in6_addr *dst,
1631             struct ospf6_interface *oi, struct ospf6_header *oh)
1632 {
1633   unsigned int len;
1634   char srcname[64], dstname[64];
1635   struct iovec iovector[2];
1636
1637   /* initialize */
1638   iovector[0].iov_base = (caddr_t) oh;
1639   iovector[0].iov_len = ntohs (oh->length);
1640   iovector[1].iov_base = NULL;
1641   iovector[1].iov_len = 0;
1642
1643   /* fill OSPF header */
1644   oh->version = OSPFV3_VERSION;
1645   /* message type must be set before */
1646   /* message length must be set before */
1647   oh->router_id = oi->area->ospf6->router_id;
1648   oh->area_id = oi->area->area_id;
1649   /* checksum is calculated by kernel */
1650   oh->instance_id = oi->instance_id;
1651   oh->reserved = 0;
1652
1653   /* Log */
1654   if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND))
1655     {
1656       inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));
1657       if (src)
1658         inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
1659       else
1660         memset (srcname, 0, sizeof (srcname));
1661       zlog_debug ("%s send on %s",
1662                  LOOKUP (ospf6_message_type_str, oh->type), oi->interface->name);
1663       zlog_debug ("    src: %s", srcname);
1664       zlog_debug ("    dst: %s", dstname);
1665
1666       switch (oh->type)
1667         {
1668           case OSPF6_MESSAGE_TYPE_HELLO:
1669             ospf6_hello_print (oh);
1670             break;
1671           case OSPF6_MESSAGE_TYPE_DBDESC:
1672             ospf6_dbdesc_print (oh);
1673             break;
1674           case OSPF6_MESSAGE_TYPE_LSREQ:
1675             ospf6_lsreq_print (oh);
1676             break;
1677           case OSPF6_MESSAGE_TYPE_LSUPDATE:
1678             ospf6_lsupdate_print (oh);
1679             break;
1680           case OSPF6_MESSAGE_TYPE_LSACK:
1681             ospf6_lsack_print (oh);
1682             break;
1683           default:
1684             zlog_debug ("Unknown message");
1685             assert (0);
1686             break;
1687         }
1688     }
1689
1690   /* send message */
1691   len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector);
1692   if (len != ntohs (oh->length))
1693     zlog_err ("Could not send entire message");
1694 }
1695
1696 static uint32_t
1697 ospf6_packet_max(struct ospf6_interface *oi)
1698 {
1699   assert (oi->ifmtu > sizeof (struct ip6_hdr));
1700   return oi->ifmtu - (sizeof (struct ip6_hdr));
1701 }
1702
1703 int
1704 ospf6_hello_send (struct thread *thread)
1705 {
1706   struct ospf6_interface *oi;
1707   struct ospf6_header *oh;
1708   struct ospf6_hello *hello;
1709   u_char *p;
1710   struct listnode *node, *nnode;
1711   struct ospf6_neighbor *on;
1712
1713   oi = (struct ospf6_interface *) THREAD_ARG (thread);
1714   oi->thread_send_hello = (struct thread *) NULL;
1715
1716   if (oi->state <= OSPF6_INTERFACE_DOWN)
1717     {
1718       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
1719         zlog_debug ("Unable to send Hello on down interface %s",
1720                    oi->interface->name);
1721       return 0;
1722     }
1723
1724   if (iobuflen == 0)
1725     {
1726       zlog_debug ("Unable to send Hello on interface %s iobuflen is 0",
1727                  oi->interface->name);
1728       return 0;
1729     }
1730
1731   /* set next thread */
1732   oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,
1733                                             oi, oi->hello_interval);
1734
1735   memset (sendbuf, 0, iobuflen);
1736   oh = (struct ospf6_header *) sendbuf;
1737   hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header));
1738
1739   hello->interface_id = htonl (oi->interface->ifindex);
1740   hello->priority = oi->priority;
1741   hello->options[0] = oi->area->options[0];
1742   hello->options[1] = oi->area->options[1];
1743   hello->options[2] = oi->area->options[2];
1744   hello->hello_interval = htons (oi->hello_interval);
1745   hello->dead_interval = htons (oi->dead_interval);
1746   hello->drouter = oi->drouter;
1747   hello->bdrouter = oi->bdrouter;
1748
1749   p = (u_char *)((caddr_t) hello + sizeof (struct ospf6_hello));
1750
1751   for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
1752     {
1753       if (on->state < OSPF6_NEIGHBOR_INIT)
1754         continue;
1755
1756       if (p - sendbuf + sizeof (u_int32_t) > ospf6_packet_max(oi))
1757         {
1758           if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
1759             zlog_debug ("sending Hello message: exceeds I/F MTU");
1760           break;
1761         }
1762
1763       memcpy (p, &on->router_id, sizeof (u_int32_t));
1764       p += sizeof (u_int32_t);
1765     }
1766
1767   oh->type = OSPF6_MESSAGE_TYPE_HELLO;
1768   oh->length = htons (p - sendbuf);
1769
1770   ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1771   return 0;
1772 }
1773
1774 int
1775 ospf6_dbdesc_send (struct thread *thread)
1776 {
1777   struct ospf6_neighbor *on;
1778   struct ospf6_header *oh;
1779   struct ospf6_dbdesc *dbdesc;
1780   u_char *p;
1781   struct ospf6_lsa *lsa;
1782   struct in6_addr *dst;
1783
1784   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1785   on->thread_send_dbdesc = (struct thread *) NULL;
1786
1787   if (on->state < OSPF6_NEIGHBOR_EXSTART)
1788     {
1789       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND))
1790         zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
1791                     on->name, ospf6_neighbor_state_str[on->state]);
1792       return 0;
1793     }
1794
1795   /* set next thread if master */
1796   if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
1797     on->thread_send_dbdesc =
1798       thread_add_timer (master, ospf6_dbdesc_send, on,
1799                         on->ospf6_if->rxmt_interval);
1800
1801   memset (sendbuf, 0, iobuflen);
1802   oh = (struct ospf6_header *) sendbuf;
1803   dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh +
1804                                    sizeof (struct ospf6_header));
1805
1806   /* if this is initial one, initialize sequence number for DbDesc */
1807   if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) &&
1808       (on->dbdesc_seqnum == 0))
1809     {
1810       struct timeval tv;
1811       if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv) < 0)
1812         tv.tv_sec = 1;
1813       on->dbdesc_seqnum = tv.tv_sec;
1814     }
1815
1816   dbdesc->options[0] = on->ospf6_if->area->options[0];
1817   dbdesc->options[1] = on->ospf6_if->area->options[1];
1818   dbdesc->options[2] = on->ospf6_if->area->options[2];
1819   dbdesc->ifmtu = htons (on->ospf6_if->ifmtu);
1820   dbdesc->bits = on->dbdesc_bits;
1821   dbdesc->seqnum = htonl (on->dbdesc_seqnum);
1822
1823   /* if this is not initial one, set LSA headers in dbdesc */
1824   p = (u_char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
1825   if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
1826     {
1827       for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
1828            lsa = ospf6_lsdb_next (lsa))
1829         {
1830           ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1831
1832           /* MTU check */
1833           if (p - sendbuf + sizeof (struct ospf6_lsa_header) >
1834               ospf6_packet_max(on->ospf6_if))
1835             {
1836               ospf6_lsdb_lsa_unlock (lsa);
1837               break;
1838             }
1839           memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
1840           p += sizeof (struct ospf6_lsa_header);
1841         }
1842     }
1843
1844   oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
1845   oh->length = htons (p - sendbuf);
1846
1847
1848   if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
1849     dst = &allspfrouters6;
1850   else
1851     dst = &on->linklocal_addr;
1852
1853   ospf6_send (on->ospf6_if->linklocal_addr, dst, on->ospf6_if, oh);
1854
1855   return 0;
1856 }
1857
1858 int
1859 ospf6_dbdesc_send_newone (struct thread *thread)
1860 {
1861   struct ospf6_neighbor *on;
1862   struct ospf6_lsa *lsa;
1863   unsigned int size = 0;
1864
1865   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1866   ospf6_lsdb_remove_all (on->dbdesc_list);
1867
1868   /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
1869      so that ospf6_send_dbdesc () can send those LSAs */
1870   size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc);
1871   for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
1872        lsa = ospf6_lsdb_next (lsa))
1873     {
1874       if (size + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
1875         {
1876           ospf6_lsdb_lsa_unlock (lsa);
1877           break;
1878         }
1879
1880       ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list);
1881       ospf6_lsdb_remove (lsa, on->summary_list);
1882       size += sizeof (struct ospf6_lsa_header);
1883     }
1884
1885   if (on->summary_list->count == 0)
1886     UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
1887
1888   /* If slave, More bit check must be done here */
1889   if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
1890       ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) &&
1891       ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
1892     thread_add_event (master, exchange_done, on, 0);
1893
1894   thread_execute (master, ospf6_dbdesc_send, on, 0);
1895   return 0;
1896 }
1897
1898 int
1899 ospf6_lsreq_send (struct thread *thread)
1900 {
1901   struct ospf6_neighbor *on;
1902   struct ospf6_header *oh;
1903   struct ospf6_lsreq_entry *e;
1904   u_char *p;
1905   struct ospf6_lsa *lsa, *last_req;
1906
1907   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1908   on->thread_send_lsreq = (struct thread *) NULL;
1909
1910   /* LSReq will be sent only in ExStart or Loading */
1911   if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1912       on->state != OSPF6_NEIGHBOR_LOADING)
1913     {
1914       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND))
1915         zlog_debug ("Quit to send LSReq to neighbor %s state %s",
1916                     on->name, ospf6_neighbor_state_str[on->state]);
1917       return 0;
1918     }
1919
1920   /* schedule loading_done if request list is empty */
1921   if (on->request_list->count == 0)
1922     {
1923       thread_add_event (master, loading_done, on, 0);
1924       return 0;
1925     }
1926
1927   memset (sendbuf, 0, iobuflen);
1928   oh = (struct ospf6_header *) sendbuf;
1929   last_req = NULL;
1930
1931   /* set Request entries in lsreq */
1932   p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
1933   for (lsa = ospf6_lsdb_head (on->request_list); lsa;
1934        lsa = ospf6_lsdb_next (lsa))
1935     {
1936       /* MTU check */
1937       if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if))
1938         {
1939           ospf6_lsdb_lsa_unlock (lsa);
1940           break;
1941         }
1942
1943       e = (struct ospf6_lsreq_entry *) p;
1944       e->type = lsa->header->type;
1945       e->id = lsa->header->id;
1946       e->adv_router = lsa->header->adv_router;
1947       p += sizeof (struct ospf6_lsreq_entry);
1948       last_req = lsa;
1949     }
1950
1951   if (last_req != NULL)
1952     {
1953       if (on->last_ls_req != NULL)
1954         {
1955           ospf6_lsa_unlock (on->last_ls_req);
1956         }
1957       ospf6_lsa_lock (last_req);
1958       on->last_ls_req = last_req;
1959     }
1960
1961   oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
1962   oh->length = htons (p - sendbuf);
1963
1964   if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
1965     ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
1966               on->ospf6_if, oh);
1967   else
1968     ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1969                 on->ospf6_if, oh);
1970
1971   /* set next thread */
1972   if (on->request_list->count != 0)
1973     {
1974       on->thread_send_lsreq =
1975         thread_add_timer (master, ospf6_lsreq_send, on,
1976                           on->ospf6_if->rxmt_interval);
1977     }
1978
1979   return 0;
1980 }
1981
1982 int
1983 ospf6_lsupdate_send_neighbor (struct thread *thread)
1984 {
1985   struct ospf6_neighbor *on;
1986   struct ospf6_header *oh;
1987   struct ospf6_lsupdate *lsupdate;
1988   u_char *p;
1989   int lsa_cnt;
1990   struct ospf6_lsa *lsa;
1991
1992   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1993   on->thread_send_lsupdate = (struct thread *) NULL;
1994
1995   if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
1996     zlog_debug ("LSUpdate to neighbor %s", on->name);
1997
1998   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
1999     {
2000       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
2001         zlog_debug ("Quit to send (neighbor state %s)",
2002                     ospf6_neighbor_state_str[on->state]);
2003       return 0;
2004     }
2005
2006   memset (sendbuf, 0, iobuflen);
2007   oh = (struct ospf6_header *) sendbuf;
2008   lsupdate = (struct ospf6_lsupdate *)
2009     ((caddr_t) oh + sizeof (struct ospf6_header));
2010
2011   p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
2012   lsa_cnt = 0;
2013
2014   /* lsupdate_list lists those LSA which doesn't need to be
2015      retransmitted. remove those from the list */
2016   for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
2017        lsa = ospf6_lsdb_next (lsa))
2018     {
2019       /* MTU check */
2020       if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
2021            > ospf6_packet_max(on->ospf6_if))
2022         {
2023           ospf6_lsdb_lsa_unlock (lsa);
2024           break;
2025         }
2026
2027       ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
2028       memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
2029       p += OSPF6_LSA_SIZE (lsa->header);
2030       lsa_cnt++;
2031
2032       assert (lsa->lock == 2);
2033       ospf6_lsdb_remove (lsa, on->lsupdate_list);
2034     }
2035
2036   if (lsa_cnt)
2037     {
2038       oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2039       oh->length = htons (p - sendbuf);
2040       lsupdate->lsa_number = htonl (lsa_cnt);
2041
2042       if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) ||
2043           (on->ospf6_if->state == OSPF6_INTERFACE_DR) ||
2044           (on->ospf6_if->state == OSPF6_INTERFACE_BDR))
2045         ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
2046                     on->ospf6_if, oh);
2047       else
2048         ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2049                     on->ospf6_if, oh);
2050     }
2051
2052   /* The addresses used for retransmissions are different from those sent the
2053      first time and so we need to separate them here.
2054   */
2055   memset (sendbuf, 0, iobuflen);
2056   oh = (struct ospf6_header *) sendbuf;
2057   lsupdate = (struct ospf6_lsupdate *)
2058     ((caddr_t) oh + sizeof (struct ospf6_header));
2059   p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
2060   lsa_cnt = 0;
2061
2062   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
2063        lsa = ospf6_lsdb_next (lsa))
2064     {
2065       /* MTU check */
2066       if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
2067            > ospf6_packet_max(on->ospf6_if))
2068         {
2069           ospf6_lsdb_lsa_unlock (lsa);
2070           break;
2071         }
2072
2073       ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
2074       memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
2075       p += OSPF6_LSA_SIZE (lsa->header);
2076       lsa_cnt++;
2077     }
2078
2079   if (lsa_cnt)
2080     {
2081       oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2082       oh->length = htons (p - sendbuf);
2083       lsupdate->lsa_number = htonl (lsa_cnt);
2084
2085       if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
2086         ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
2087                     on->ospf6_if, oh);
2088       else
2089         ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2090                     on->ospf6_if, oh);
2091     }
2092
2093   if (on->lsupdate_list->count != 0)
2094     on->thread_send_lsupdate =
2095       thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
2096   else if (on->retrans_list->count != 0)
2097     on->thread_send_lsupdate =
2098       thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
2099                         on->ospf6_if->rxmt_interval);
2100   return 0;
2101 }
2102
2103 int
2104 ospf6_lsupdate_send_interface (struct thread *thread)
2105 {
2106   struct ospf6_interface *oi;
2107   struct ospf6_header *oh;
2108   struct ospf6_lsupdate *lsupdate;
2109   u_char *p;
2110   int lsa_cnt;
2111   struct ospf6_lsa *lsa;
2112
2113   oi = (struct ospf6_interface *) THREAD_ARG (thread);
2114   oi->thread_send_lsupdate = (struct thread *) NULL;
2115
2116   if (oi->state <= OSPF6_INTERFACE_WAITING)
2117     {
2118       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
2119         zlog_debug ("Quit to send LSUpdate to interface %s state %s",
2120                     oi->interface->name, ospf6_interface_state_str[oi->state]);
2121       return 0;
2122     }
2123
2124   /* if we have nothing to send, return */
2125   if (oi->lsupdate_list->count == 0)
2126     return 0;
2127
2128   memset (sendbuf, 0, iobuflen);
2129   oh = (struct ospf6_header *) sendbuf;
2130   lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
2131                                        sizeof (struct ospf6_header));
2132
2133   p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
2134   lsa_cnt = 0;
2135
2136   for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
2137        lsa = ospf6_lsdb_next (lsa))
2138     {
2139       /* MTU check */
2140       if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
2141            > ospf6_packet_max(oi))
2142         {
2143           ospf6_lsdb_lsa_unlock (lsa);
2144           break;
2145         }
2146
2147       ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
2148       memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
2149       p += OSPF6_LSA_SIZE (lsa->header);
2150       lsa_cnt++;
2151
2152       assert (lsa->lock == 2);
2153       ospf6_lsdb_remove (lsa, oi->lsupdate_list);
2154     }
2155
2156   if (lsa_cnt)
2157     {
2158       lsupdate->lsa_number = htonl (lsa_cnt);
2159
2160       oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2161       oh->length = htons (p - sendbuf);
2162
2163       if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
2164           (oi->state == OSPF6_INTERFACE_DR) ||
2165           (oi->state == OSPF6_INTERFACE_BDR))
2166         ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
2167       else
2168         ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
2169
2170     }
2171
2172   if (oi->lsupdate_list->count > 0)
2173     {
2174       oi->thread_send_lsupdate =
2175         thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
2176     }
2177
2178   return 0;
2179 }
2180
2181 int
2182 ospf6_lsack_send_neighbor (struct thread *thread)
2183 {
2184   struct ospf6_neighbor *on;
2185   struct ospf6_header *oh;
2186   u_char *p;
2187   struct ospf6_lsa *lsa;
2188   int lsa_cnt = 0;
2189
2190   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
2191   on->thread_send_lsack = (struct thread *) NULL;
2192
2193   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
2194     {
2195       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
2196         zlog_debug ("Quit to send LSAck to neighbor %s state %s",
2197                     on->name, ospf6_neighbor_state_str[on->state]);
2198       return 0;
2199     }
2200
2201   /* if we have nothing to send, return */
2202   if (on->lsack_list->count == 0)
2203     return 0;
2204
2205   memset (sendbuf, 0, iobuflen);
2206   oh = (struct ospf6_header *) sendbuf;
2207
2208   p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
2209
2210   for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
2211        lsa = ospf6_lsdb_next (lsa))
2212     {
2213       /* MTU check */
2214       if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
2215         {
2216           /* if we run out of packet size/space here,
2217              better to try again soon. */
2218           THREAD_OFF (on->thread_send_lsack);
2219           on->thread_send_lsack =
2220             thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
2221
2222           ospf6_lsdb_lsa_unlock (lsa);
2223           break;
2224         }
2225
2226       ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
2227       memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
2228       p += sizeof (struct ospf6_lsa_header);
2229
2230       assert (lsa->lock == 2);
2231       ospf6_lsdb_remove (lsa, on->lsack_list);
2232       lsa_cnt++;
2233     }
2234
2235   if (lsa_cnt)
2236     {
2237       oh->type = OSPF6_MESSAGE_TYPE_LSACK;
2238       oh->length = htons (p - sendbuf);
2239
2240       ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2241                   on->ospf6_if, oh);
2242     }
2243
2244   if (on->thread_send_lsack == NULL && on->lsack_list->count > 0)
2245     {
2246       on->thread_send_lsack =
2247         thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
2248     }
2249
2250   return 0;
2251 }
2252
2253 int
2254 ospf6_lsack_send_interface (struct thread *thread)
2255 {
2256   struct ospf6_interface *oi;
2257   struct ospf6_header *oh;
2258   u_char *p;
2259   struct ospf6_lsa *lsa;
2260   int lsa_cnt = 0;
2261
2262   oi = (struct ospf6_interface *) THREAD_ARG (thread);
2263   oi->thread_send_lsack = (struct thread *) NULL;
2264
2265   if (oi->state <= OSPF6_INTERFACE_WAITING)
2266     {
2267       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
2268         zlog_debug ("Quit to send LSAck to interface %s state %s",
2269                     oi->interface->name, ospf6_interface_state_str[oi->state]);
2270       return 0;
2271     }
2272
2273   /* if we have nothing to send, return */
2274   if (oi->lsack_list->count == 0)
2275     return 0;
2276
2277   memset (sendbuf, 0, iobuflen);
2278   oh = (struct ospf6_header *) sendbuf;
2279
2280   p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
2281
2282   for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
2283        lsa = ospf6_lsdb_next (lsa))
2284     {
2285       /* MTU check */
2286       if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi))
2287         {
2288           /* if we run out of packet size/space here,
2289              better to try again soon. */
2290           THREAD_OFF (oi->thread_send_lsack);
2291           oi->thread_send_lsack =
2292             thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
2293
2294           ospf6_lsdb_lsa_unlock (lsa);
2295           break;
2296         }
2297
2298       ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
2299       memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
2300       p += sizeof (struct ospf6_lsa_header);
2301
2302       assert (lsa->lock == 2);
2303       ospf6_lsdb_remove (lsa, oi->lsack_list);
2304       lsa_cnt++;
2305     }
2306
2307   if (lsa_cnt)
2308     {
2309       oh->type = OSPF6_MESSAGE_TYPE_LSACK;
2310       oh->length = htons (p - sendbuf);
2311
2312       if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
2313           (oi->state == OSPF6_INTERFACE_DR) ||
2314           (oi->state == OSPF6_INTERFACE_BDR))
2315         ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
2316       else
2317         ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
2318     }
2319
2320   if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
2321     {
2322       oi->thread_send_lsack =
2323         thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
2324     }
2325
2326   return 0;
2327 }
2328
2329
2330 /* Commands */
2331 DEFUN (debug_ospf6_message,
2332        debug_ospf6_message_cmd,
2333        "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
2334        DEBUG_STR
2335        OSPF6_STR
2336        "Debug OSPFv3 message\n"
2337        "Debug Unknown message\n"
2338        "Debug Hello message\n"
2339        "Debug Database Description message\n"
2340        "Debug Link State Request message\n"
2341        "Debug Link State Update message\n"
2342        "Debug Link State Acknowledgement message\n"
2343        "Debug All message\n"
2344        )
2345 {
2346   unsigned char level = 0;
2347   int type = 0;
2348   int i;
2349
2350   assert (argc > 0);
2351
2352   /* check type */
2353   if (! strncmp (argv[0], "u", 1))
2354     type = OSPF6_MESSAGE_TYPE_UNKNOWN;
2355   else if (! strncmp (argv[0], "h", 1))
2356     type = OSPF6_MESSAGE_TYPE_HELLO;
2357   else if (! strncmp (argv[0], "d", 1))
2358     type = OSPF6_MESSAGE_TYPE_DBDESC;
2359   else if (! strncmp (argv[0], "lsr", 3))
2360     type = OSPF6_MESSAGE_TYPE_LSREQ;
2361   else if (! strncmp (argv[0], "lsu", 3))
2362     type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2363   else if (! strncmp (argv[0], "lsa", 3))
2364     type = OSPF6_MESSAGE_TYPE_LSACK;
2365   else if (! strncmp (argv[0], "a", 1))
2366     type = OSPF6_MESSAGE_TYPE_ALL;
2367
2368   if (argc == 1)
2369     level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
2370   else if (! strncmp (argv[1], "s", 1))
2371     level = OSPF6_DEBUG_MESSAGE_SEND;
2372   else if (! strncmp (argv[1], "r", 1))
2373     level = OSPF6_DEBUG_MESSAGE_RECV;
2374
2375   if (type == OSPF6_MESSAGE_TYPE_ALL)
2376     {
2377       for (i = 0; i < 6; i++)
2378         OSPF6_DEBUG_MESSAGE_ON (i, level);
2379     }
2380   else
2381     OSPF6_DEBUG_MESSAGE_ON (type, level);
2382
2383   return CMD_SUCCESS;
2384 }
2385
2386 ALIAS (debug_ospf6_message,
2387        debug_ospf6_message_sendrecv_cmd,
2388        "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
2389        DEBUG_STR
2390        OSPF6_STR
2391        "Debug OSPFv3 message\n"
2392        "Debug Unknown message\n"
2393        "Debug Hello message\n"
2394        "Debug Database Description message\n"
2395        "Debug Link State Request message\n"
2396        "Debug Link State Update message\n"
2397        "Debug Link State Acknowledgement message\n"
2398        "Debug All message\n"
2399        "Debug only sending message\n"
2400        "Debug only receiving message\n"
2401        )
2402
2403
2404 DEFUN (no_debug_ospf6_message,
2405        no_debug_ospf6_message_cmd,
2406        "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
2407        NO_STR
2408        DEBUG_STR
2409        OSPF6_STR
2410        "Debug OSPFv3 message\n"
2411        "Debug Unknown message\n"
2412        "Debug Hello message\n"
2413        "Debug Database Description message\n"
2414        "Debug Link State Request message\n"
2415        "Debug Link State Update message\n"
2416        "Debug Link State Acknowledgement message\n"
2417        "Debug All message\n"
2418        )
2419 {
2420   unsigned char level = 0;
2421   int type = 0;
2422   int i;
2423
2424   assert (argc > 0);
2425
2426   /* check type */
2427   if (! strncmp (argv[0], "u", 1))
2428     type = OSPF6_MESSAGE_TYPE_UNKNOWN;
2429   else if (! strncmp (argv[0], "h", 1))
2430     type = OSPF6_MESSAGE_TYPE_HELLO;
2431   else if (! strncmp (argv[0], "d", 1))
2432     type = OSPF6_MESSAGE_TYPE_DBDESC;
2433   else if (! strncmp (argv[0], "lsr", 3))
2434     type = OSPF6_MESSAGE_TYPE_LSREQ;
2435   else if (! strncmp (argv[0], "lsu", 3))
2436     type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2437   else if (! strncmp (argv[0], "lsa", 3))
2438     type = OSPF6_MESSAGE_TYPE_LSACK;
2439   else if (! strncmp (argv[0], "a", 1))
2440     type = OSPF6_MESSAGE_TYPE_ALL;
2441
2442   if (argc == 1)
2443     level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
2444   else if (! strncmp (argv[1], "s", 1))
2445     level = OSPF6_DEBUG_MESSAGE_SEND;
2446   else if (! strncmp (argv[1], "r", 1))
2447     level = OSPF6_DEBUG_MESSAGE_RECV;
2448
2449   if (type == OSPF6_MESSAGE_TYPE_ALL)
2450     {
2451       for (i = 0; i < 6; i++)
2452         OSPF6_DEBUG_MESSAGE_OFF (i, level);
2453     }
2454   else
2455     OSPF6_DEBUG_MESSAGE_OFF (type, level);
2456
2457   return CMD_SUCCESS;
2458 }
2459
2460 ALIAS (no_debug_ospf6_message,
2461        no_debug_ospf6_message_sendrecv_cmd,
2462        "no debug ospf6 message "
2463        "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
2464        NO_STR
2465        DEBUG_STR
2466        OSPF6_STR
2467        "Debug OSPFv3 message\n"
2468        "Debug Unknown message\n"
2469        "Debug Hello message\n"
2470        "Debug Database Description message\n"
2471        "Debug Link State Request message\n"
2472        "Debug Link State Update message\n"
2473        "Debug Link State Acknowledgement message\n"
2474        "Debug All message\n"
2475        "Debug only sending message\n"
2476        "Debug only receiving message\n"
2477        )
2478
2479 int
2480 config_write_ospf6_debug_message (struct vty *vty)
2481 {
2482   const char *type_str[] = {"unknown", "hello", "dbdesc",
2483                       "lsreq", "lsupdate", "lsack"};
2484   unsigned char s = 0, r = 0;
2485   int i;
2486
2487   for (i = 0; i < 6; i++)
2488     {
2489       if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2490         s |= 1 << i;
2491       if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2492         r |= 1 << i;
2493     }
2494
2495   if (s == 0x3f && r == 0x3f)
2496     {
2497       vty_out (vty, "debug ospf6 message all%s", VNL);
2498       return 0;
2499     }
2500
2501   if (s == 0x3f && r == 0)
2502     {
2503       vty_out (vty, "debug ospf6 message all send%s", VNL);
2504       return 0;
2505     }
2506   else if (s == 0 && r == 0x3f)
2507     {
2508       vty_out (vty, "debug ospf6 message all recv%s", VNL);
2509       return 0;
2510     }
2511
2512   /* Unknown message is logged by default */
2513   if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) &&
2514       ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
2515     vty_out (vty, "no debug ospf6 message unknown%s", VNL);
2516   else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
2517     vty_out (vty, "no debug ospf6 message unknown send%s", VNL);
2518   else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
2519     vty_out (vty, "no debug ospf6 message unknown recv%s", VNL);
2520
2521   for (i = 1; i < 6; i++)
2522     {
2523       if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) &&
2524           IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2525         vty_out (vty, "debug ospf6 message %s%s", type_str[i], VNL);
2526       else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2527         vty_out (vty, "debug ospf6 message %s send%s", type_str[i],
2528                  VNL);
2529       else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2530         vty_out (vty, "debug ospf6 message %s recv%s", type_str[i],
2531                  VNL);
2532     }
2533
2534   return 0;
2535 }
2536
2537 void
2538 install_element_ospf6_debug_message (void)
2539 {
2540   install_element (ENABLE_NODE, &debug_ospf6_message_cmd);
2541   install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd);
2542   install_element (ENABLE_NODE, &debug_ospf6_message_sendrecv_cmd);
2543   install_element (ENABLE_NODE, &no_debug_ospf6_message_sendrecv_cmd);
2544   install_element (CONFIG_NODE, &debug_ospf6_message_cmd);
2545   install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd);
2546   install_element (CONFIG_NODE, &debug_ospf6_message_sendrecv_cmd);
2547   install_element (CONFIG_NODE, &no_debug_ospf6_message_sendrecv_cmd);
2548 }
2549
2550