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