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