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