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