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