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