]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_message.c
Merge pull request #13060 from opensourcerouting/feature/allow_peering_with_127.0.0.1
[mirror_frr.git] / ospf6d / ospf6_message.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2003 Yasuhiro Ohara
4 */
5
6 #include <zebra.h>
7
8 #include "memory.h"
9 #include "log.h"
10 #include "vty.h"
11 #include "command.h"
12 #include "frrevent.h"
13 #include "linklist.h"
14 #include "lib_errors.h"
15 #include "checksum.h"
16 #include "network.h"
17
18 #include "ospf6_proto.h"
19 #include "ospf6_lsa.h"
20 #include "ospf6_lsdb.h"
21 #include "ospf6_top.h"
22 #include "ospf6_network.h"
23 #include "ospf6_message.h"
24
25 #include "ospf6_area.h"
26 #include "ospf6_neighbor.h"
27 #include "ospf6_interface.h"
28
29 /* for structures and macros ospf6_lsa_examin() needs */
30 #include "ospf6_abr.h"
31 #include "ospf6_asbr.h"
32 #include "ospf6_intra.h"
33
34 #include "ospf6_flood.h"
35 #include "ospf6d.h"
36 #include "ospf6_gr.h"
37 #include <netinet/ip6.h>
38 #include "lib/libospf.h"
39 #include "lib/keychain.h"
40 #include "ospf6_auth_trailer.h"
41
42 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_MESSAGE, "OSPF6 message");
43 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PACKET, "OSPF6 packet");
44 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_FIFO, "OSPF6 FIFO queue");
45
46 unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
47
48 const char *ospf6_message_type(int type)
49 {
50 switch (type) {
51 case OSPF6_MESSAGE_TYPE_HELLO:
52 return "Hello";
53 case OSPF6_MESSAGE_TYPE_DBDESC:
54 return "DbDesc";
55 case OSPF6_MESSAGE_TYPE_LSREQ:
56 return "LSReq";
57 case OSPF6_MESSAGE_TYPE_LSUPDATE:
58 return "LSUpdate";
59 case OSPF6_MESSAGE_TYPE_LSACK:
60 return "LSAck";
61 case OSPF6_MESSAGE_TYPE_UNKNOWN:
62 default:
63 return "unknown";
64 }
65 }
66
67 /* Minimum (besides the standard OSPF packet header) lengths for OSPF
68 packets of particular types, offset is the "type" field. */
69 const uint16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] = {
70 0,
71 OSPF6_HELLO_MIN_SIZE,
72 OSPF6_DB_DESC_MIN_SIZE,
73 OSPF6_LS_REQ_MIN_SIZE,
74 OSPF6_LS_UPD_MIN_SIZE,
75 OSPF6_LS_ACK_MIN_SIZE};
76
77 /* Minimum (besides the standard LSA header) lengths for LSAs of particular
78 types, offset is the "LSA function code" portion of "LSA type" field. */
79 const uint16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] = {
80 0,
81 /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE,
82 /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE,
83 /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
84 /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE,
85 /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
86 /* 0x2006 */ 0,
87 /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
88 /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE,
89 /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE,
90 /* 0x200a */ 0,
91 /* 0x000b */ OSPF6_GRACE_LSA_MIN_SIZE};
92
93 /* print functions */
94
95 static void ospf6_header_print(struct ospf6_header *oh)
96 {
97 zlog_debug(" OSPFv%d Type:%d Len:%hu Router-ID:%pI4", oh->version,
98 oh->type, ntohs(oh->length), &oh->router_id);
99 zlog_debug(" Area-ID:%pI4 Cksum:%hx Instance-ID:%d", &oh->area_id,
100 ntohs(oh->checksum), oh->instance_id);
101 }
102
103 void ospf6_hello_print(struct ospf6_header *oh, int action)
104 {
105 struct ospf6_hello *hello;
106 char options[32];
107 char *p;
108
109 ospf6_header_print(oh);
110 assert(oh->type == OSPF6_MESSAGE_TYPE_HELLO);
111
112 hello = (struct ospf6_hello *)((caddr_t)oh
113 + sizeof(struct ospf6_header));
114
115 ospf6_options_printbuf(hello->options, options, sizeof(options));
116
117 zlog_debug(" I/F-Id:%ld Priority:%d Option:%s",
118 (unsigned long)ntohl(hello->interface_id), hello->priority,
119 options);
120 zlog_debug(" HelloInterval:%hu DeadInterval:%hu",
121 ntohs(hello->hello_interval), ntohs(hello->dead_interval));
122 zlog_debug(" DR:%pI4 BDR:%pI4", &hello->drouter, &hello->bdrouter);
123
124 if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
125 && action == OSPF6_ACTION_RECV)
126 || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
127 && action == OSPF6_ACTION_SEND)) {
128
129 for (p = (char *)((caddr_t)hello + sizeof(struct ospf6_hello));
130 p + sizeof(uint32_t) <= OSPF6_MESSAGE_END(oh);
131 p += sizeof(uint32_t))
132 zlog_debug(" Neighbor: %pI4", (in_addr_t *)p);
133
134 assert(p == OSPF6_MESSAGE_END(oh));
135 }
136 }
137
138 void ospf6_dbdesc_print(struct ospf6_header *oh, int action)
139 {
140 struct ospf6_dbdesc *dbdesc;
141 char options[32];
142 char *p;
143
144 ospf6_header_print(oh);
145 assert(oh->type == OSPF6_MESSAGE_TYPE_DBDESC);
146
147 dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh
148 + sizeof(struct ospf6_header));
149
150 ospf6_options_printbuf(dbdesc->options, options, sizeof(options));
151
152 zlog_debug(" MBZ: %#x Option: %s IfMTU: %hu", dbdesc->reserved1,
153 options, ntohs(dbdesc->ifmtu));
154 zlog_debug(" MBZ: %#x Bits: %s%s%s SeqNum: %#lx", dbdesc->reserved2,
155 (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"),
156 (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"),
157 (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"),
158 (unsigned long)ntohl(dbdesc->seqnum));
159
160 if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
161 && action == OSPF6_ACTION_RECV)
162 || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
163 && action == OSPF6_ACTION_SEND)) {
164
165 for (p = (char *)((caddr_t)dbdesc
166 + sizeof(struct ospf6_dbdesc));
167 p + sizeof(struct ospf6_lsa_header)
168 <= OSPF6_MESSAGE_END(oh);
169 p += sizeof(struct ospf6_lsa_header))
170 ospf6_lsa_header_print_raw(
171 (struct ospf6_lsa_header *)p);
172
173 assert(p == OSPF6_MESSAGE_END(oh));
174 }
175 }
176
177 void ospf6_lsreq_print(struct ospf6_header *oh, int action)
178 {
179 char *p;
180
181 ospf6_header_print(oh);
182 assert(oh->type == OSPF6_MESSAGE_TYPE_LSREQ);
183
184 if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
185 && action == OSPF6_ACTION_RECV)
186 || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
187 && action == OSPF6_ACTION_SEND)) {
188
189 for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header));
190 p + sizeof(struct ospf6_lsreq_entry)
191 <= OSPF6_MESSAGE_END(oh);
192 p += sizeof(struct ospf6_lsreq_entry)) {
193 struct ospf6_lsreq_entry *e =
194 (struct ospf6_lsreq_entry *)p;
195
196 zlog_debug(" [%s Id:%pI4 Adv:%pI4]",
197 ospf6_lstype_name(e->type), &e->id,
198 &e->adv_router);
199 }
200
201 assert(p == OSPF6_MESSAGE_END(oh));
202 }
203 }
204
205 void ospf6_lsupdate_print(struct ospf6_header *oh, int action)
206 {
207 struct ospf6_lsupdate *lsupdate;
208 unsigned long num;
209 char *p;
210
211 ospf6_header_print(oh);
212 assert(oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE);
213
214 lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh
215 + sizeof(struct ospf6_header));
216
217 num = ntohl(lsupdate->lsa_number);
218 zlog_debug(" Number of LSA: %ld", num);
219
220 if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
221 && action == OSPF6_ACTION_RECV)
222 || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
223 && action == OSPF6_ACTION_SEND)) {
224
225 for (p = (char *)((caddr_t)lsupdate
226 + sizeof(struct ospf6_lsupdate));
227 p < OSPF6_MESSAGE_END(oh)
228 && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh);
229 p += OSPF6_LSA_SIZE(p)) {
230 ospf6_lsa_header_print_raw(
231 (struct ospf6_lsa_header *)p);
232 }
233
234 assert(p == OSPF6_MESSAGE_END(oh));
235 }
236 }
237
238 void ospf6_lsack_print(struct ospf6_header *oh, int action)
239 {
240 char *p;
241
242 ospf6_header_print(oh);
243 assert(oh->type == OSPF6_MESSAGE_TYPE_LSACK);
244
245 if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
246 && action == OSPF6_ACTION_RECV)
247 || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
248 && action == OSPF6_ACTION_SEND)) {
249
250 for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header));
251 p + sizeof(struct ospf6_lsa_header)
252 <= OSPF6_MESSAGE_END(oh);
253 p += sizeof(struct ospf6_lsa_header))
254 ospf6_lsa_header_print_raw(
255 (struct ospf6_lsa_header *)p);
256
257 assert(p == OSPF6_MESSAGE_END(oh));
258 }
259 }
260
261 static struct ospf6_packet *ospf6_packet_new(size_t size)
262 {
263 struct ospf6_packet *new;
264
265 new = XCALLOC(MTYPE_OSPF6_PACKET, sizeof(struct ospf6_packet));
266 new->s = stream_new(size);
267
268 return new;
269 }
270
271 static void ospf6_packet_free(struct ospf6_packet *op)
272 {
273 if (op->s)
274 stream_free(op->s);
275
276 XFREE(MTYPE_OSPF6_PACKET, op);
277 }
278
279 struct ospf6_fifo *ospf6_fifo_new(void)
280 {
281 struct ospf6_fifo *new;
282
283 new = XCALLOC(MTYPE_OSPF6_FIFO, sizeof(struct ospf6_fifo));
284 return new;
285 }
286
287 /* Add new packet to fifo. */
288 static void ospf6_fifo_push(struct ospf6_fifo *fifo, struct ospf6_packet *op)
289 {
290 if (fifo->tail)
291 fifo->tail->next = op;
292 else
293 fifo->head = op;
294
295 fifo->tail = op;
296
297 fifo->count++;
298 }
299
300 /* Add new packet to head of fifo. */
301 static void ospf6_fifo_push_head(struct ospf6_fifo *fifo,
302 struct ospf6_packet *op)
303 {
304 op->next = fifo->head;
305
306 if (fifo->tail == NULL)
307 fifo->tail = op;
308
309 fifo->head = op;
310
311 fifo->count++;
312 }
313
314 /* Delete first packet from fifo. */
315 static struct ospf6_packet *ospf6_fifo_pop(struct ospf6_fifo *fifo)
316 {
317 struct ospf6_packet *op;
318
319 op = fifo->head;
320
321 if (op) {
322 fifo->head = op->next;
323
324 if (fifo->head == NULL)
325 fifo->tail = NULL;
326
327 fifo->count--;
328 }
329
330 return op;
331 }
332
333 /* Return first fifo entry. */
334 static struct ospf6_packet *ospf6_fifo_head(struct ospf6_fifo *fifo)
335 {
336 return fifo->head;
337 }
338
339 /* Flush ospf packet fifo. */
340 void ospf6_fifo_flush(struct ospf6_fifo *fifo)
341 {
342 struct ospf6_packet *op;
343 struct ospf6_packet *next;
344
345 for (op = fifo->head; op; op = next) {
346 next = op->next;
347 ospf6_packet_free(op);
348 }
349 fifo->head = fifo->tail = NULL;
350 fifo->count = 0;
351 }
352
353 /* Free ospf packet fifo. */
354 void ospf6_fifo_free(struct ospf6_fifo *fifo)
355 {
356 ospf6_fifo_flush(fifo);
357
358 XFREE(MTYPE_OSPF6_FIFO, fifo);
359 }
360
361 static void ospf6_packet_add(struct ospf6_interface *oi,
362 struct ospf6_packet *op)
363 {
364 /* Add packet to end of queue. */
365 ospf6_fifo_push(oi->obuf, op);
366
367 /* Debug of packet fifo*/
368 /* ospf_fifo_debug (oi->obuf); */
369 }
370
371 static void ospf6_packet_add_top(struct ospf6_interface *oi,
372 struct ospf6_packet *op)
373 {
374 /* Add packet to head of queue. */
375 ospf6_fifo_push_head(oi->obuf, op);
376
377 /* Debug of packet fifo*/
378 /* ospf_fifo_debug (oi->obuf); */
379 }
380
381 static void ospf6_packet_delete(struct ospf6_interface *oi)
382 {
383 struct ospf6_packet *op;
384
385 op = ospf6_fifo_pop(oi->obuf);
386
387 if (op)
388 ospf6_packet_free(op);
389 }
390
391
392 static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst,
393 struct ospf6_interface *oi,
394 struct ospf6_header *oh)
395 {
396 struct ospf6_hello *hello;
397 struct ospf6_neighbor *on;
398 char *p;
399 int twoway = 0;
400 int neighborchange = 0;
401 int neighbor_ifindex_change = 0;
402 int backupseen = 0;
403 int64_t latency = 0;
404 struct timeval timestamp;
405
406 monotime(&timestamp);
407 hello = (struct ospf6_hello *)((caddr_t)oh
408 + sizeof(struct ospf6_header));
409
410 /* HelloInterval check */
411 if (ntohs(hello->hello_interval) != oi->hello_interval) {
412 zlog_warn(
413 "VRF %s: I/F %s HelloInterval mismatch from %pI6 (%pI4): (my %d, rcvd %d)",
414 oi->interface->vrf->name, oi->interface->name, src,
415 &oh->router_id, oi->hello_interval,
416 ntohs(hello->hello_interval));
417 return;
418 }
419
420 /* RouterDeadInterval check */
421 if (ntohs(hello->dead_interval) != oi->dead_interval) {
422 zlog_warn(
423 "VRF %s: I/F %s DeadInterval mismatch from %pI6 (%pI4): (my %d, rcvd %d)",
424 oi->interface->vrf->name, oi->interface->name, src,
425 &oh->router_id, oi->dead_interval,
426 ntohs(hello->dead_interval));
427 return;
428 }
429
430 /* E-bit check */
431 if (OSPF6_OPT_ISSET(hello->options, OSPF6_OPT_E) !=
432 OSPF6_OPT_ISSET(oi->area->options, OSPF6_OPT_E)) {
433 zlog_warn("VRF %s: IF %s E-bit mismatch from %pI6 (%pI4)",
434 oi->interface->vrf->name, oi->interface->name, src,
435 &oh->router_id);
436 return;
437 }
438
439 /* N-bit check */
440 if (OSPF6_OPT_ISSET(hello->options, OSPF6_OPT_N)
441 != OSPF6_OPT_ISSET(oi->area->options, OSPF6_OPT_N)) {
442 zlog_warn("VRF %s: IF %s N-bit mismatch",
443 oi->interface->vrf->name, oi->interface->name);
444 return;
445 }
446
447 if (((OSPF6_OPT_ISSET_EXT(hello->options, OSPF6_OPT_AT) ==
448 OSPF6_OPT_AT) &&
449 (oi->at_data.flags == 0)) ||
450 ((OSPF6_OPT_ISSET_EXT(hello->options, OSPF6_OPT_AT) !=
451 OSPF6_OPT_AT) &&
452 (oi->at_data.flags != 0))) {
453 if (IS_OSPF6_DEBUG_AUTH_RX)
454 zlog_warn(
455 "VRF %s: IF %s AT-bit mismatch in hello packet",
456 oi->interface->vrf->name, oi->interface->name);
457 oi->at_data.rx_drop++;
458 return;
459 }
460
461 /* Find neighbor, create if not exist */
462 on = ospf6_neighbor_lookup(oh->router_id, oi);
463 if (on == NULL) {
464 on = ospf6_neighbor_create(oh->router_id, oi);
465 on->prev_drouter = on->drouter = hello->drouter;
466 on->prev_bdrouter = on->bdrouter = hello->bdrouter;
467 on->priority = hello->priority;
468 }
469
470 /* check latency against hello period */
471 if (on->hello_in)
472 latency = monotime_since(&on->last_hello, NULL)
473 - ((int64_t)oi->hello_interval * 1000000);
474 /* log if latency exceeds the hello period */
475 if (latency > ((int64_t)oi->hello_interval * 1000000))
476 zlog_warn("%s RX %pI4 high latency %" PRId64 "us.", __func__,
477 &on->router_id, latency);
478 on->last_hello = timestamp;
479 on->hello_in++;
480
481 /* Always override neighbor's source address */
482 memcpy(&on->linklocal_addr, src, sizeof(struct in6_addr));
483
484 /* Neighbor ifindex check */
485 if (on->ifindex != (ifindex_t)ntohl(hello->interface_id)) {
486 on->ifindex = ntohl(hello->interface_id);
487 neighbor_ifindex_change++;
488 }
489
490 /* TwoWay check */
491 for (p = (char *)((caddr_t)hello + sizeof(struct ospf6_hello));
492 p + sizeof(uint32_t) <= OSPF6_MESSAGE_END(oh);
493 p += sizeof(uint32_t)) {
494 uint32_t *router_id = (uint32_t *)p;
495
496 if (*router_id == oi->area->ospf6->router_id)
497 twoway++;
498 }
499
500 assert(p == OSPF6_MESSAGE_END(oh));
501
502 /* RouterPriority check */
503 if (on->priority != hello->priority) {
504 on->priority = hello->priority;
505 neighborchange++;
506 }
507
508 /* DR check */
509 if (on->drouter != hello->drouter) {
510 on->prev_drouter = on->drouter;
511 on->drouter = hello->drouter;
512 if (on->prev_drouter == on->router_id
513 || on->drouter == on->router_id)
514 neighborchange++;
515 }
516
517 /* BDR check */
518 if (on->bdrouter != hello->bdrouter) {
519 on->prev_bdrouter = on->bdrouter;
520 on->bdrouter = hello->bdrouter;
521 if (on->prev_bdrouter == on->router_id
522 || on->bdrouter == on->router_id)
523 neighborchange++;
524 }
525
526 /* BackupSeen check */
527 if (oi->state == OSPF6_INTERFACE_WAITING) {
528 if (hello->bdrouter == on->router_id)
529 backupseen++;
530 else if (hello->drouter == on->router_id
531 && hello->bdrouter == htonl(0))
532 backupseen++;
533 }
534
535 oi->hello_in++;
536
537 /* Execute neighbor events */
538 event_execute(master, hello_received, on, 0);
539 if (twoway)
540 event_execute(master, twoway_received, on, 0);
541 else {
542 if (OSPF6_GR_IS_ACTIVE_HELPER(on)) {
543 if (IS_DEBUG_OSPF6_GR)
544 zlog_debug(
545 "%s, Received oneway hello from RESTARTER so ignore here.",
546 __PRETTY_FUNCTION__);
547 } else {
548 /* If the router is DR_OTHER, RESTARTER will not wait
549 * until it receives the hello from it if it receives
550 * from DR and BDR.
551 * So, helper might receives ONE_WAY hello from
552 * RESTARTER. So not allowing to change the state if it
553 * receives one_way hellow when it acts as HELPER for
554 * that specific neighbor.
555 */
556 event_execute(master, oneway_received, on, 0);
557 }
558 }
559
560 if (OSPF6_GR_IS_ACTIVE_HELPER(on)) {
561 /* As per the GR Conformance Test Case 7.2. Section 3
562 * "Also, if X was the Designated Router on network segment S
563 * when the helping relationship began, Y maintains X as the
564 * Designated Router until the helping relationship is
565 * terminated."
566 * When it is a helper for this neighbor, It should not trigger
567 * the ISM Events. Also Intentionally not setting the priority
568 * and other fields so that when the neighbor exits the Grace
569 * period, it can handle if there is any change before GR and
570 * after GR.
571 */
572 if (IS_DEBUG_OSPF6_GR)
573 zlog_debug(
574 "%s, Neighbor is under GR Restart, hence ignoring the ISM Events",
575 __PRETTY_FUNCTION__);
576
577 return;
578 }
579
580 /*
581 * RFC 3623 - Section 2:
582 * "If the restarting router determines that it was the Designated
583 * Router on a given segment prior to the restart, it elects
584 * itself as the Designated Router again. The restarting router
585 * knows that it was the Designated Router if, while the
586 * associated interface is in Waiting state, a Hello packet is
587 * received from a neighbor listing the router as the Designated
588 * Router".
589 */
590 if (oi->area->ospf6->gr_info.restart_in_progress
591 && oi->state == OSPF6_INTERFACE_WAITING
592 && hello->drouter == oi->area->ospf6->router_id)
593 oi->drouter = hello->drouter;
594
595 /* Schedule interface events */
596 if (backupseen)
597 event_add_event(master, backup_seen, oi, 0, NULL);
598 if (neighborchange)
599 event_add_event(master, neighbor_change, oi, 0, NULL);
600
601 if (neighbor_ifindex_change && on->state == OSPF6_NEIGHBOR_FULL)
602 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
603 }
604
605 static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
606 struct ospf6_neighbor *on)
607 {
608 struct ospf6_dbdesc *dbdesc;
609 char *p;
610
611 dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh
612 + sizeof(struct ospf6_header));
613
614 if (on->state < OSPF6_NEIGHBOR_INIT) {
615 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
616 zlog_debug("Neighbor state less than Init, ignore");
617 return;
618 }
619
620 switch (on->state) {
621 case OSPF6_NEIGHBOR_TWOWAY:
622 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
623 zlog_debug("Neighbor state is 2-Way, ignore");
624 return;
625
626 case OSPF6_NEIGHBOR_INIT:
627 event_execute(master, twoway_received, on, 0);
628 if (on->state != OSPF6_NEIGHBOR_EXSTART) {
629 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
630 zlog_debug(
631 "Neighbor state is not ExStart, ignore");
632 return;
633 }
634 /* else fall through to ExStart */
635 /* fallthru */
636 case OSPF6_NEIGHBOR_EXSTART:
637 /* if neighbor obeys us as our slave, schedule negotiation_done
638 and process LSA Headers. Otherwise, ignore this message */
639 if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)
640 && !CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)
641 && ntohl(dbdesc->seqnum) == on->dbdesc_seqnum) {
642 /* execute NegotiationDone */
643 event_execute(master, negotiation_done, on, 0);
644
645 /* Record neighbor options */
646 memcpy(on->options, dbdesc->options,
647 sizeof(on->options));
648 } else {
649 zlog_warn("VRF %s: Nbr %s: Negotiation failed",
650 on->ospf6_if->interface->vrf->name, on->name);
651 return;
652 }
653 /* fall through to exchange */
654
655 case OSPF6_NEIGHBOR_EXCHANGE:
656 if (!memcmp(dbdesc, &on->dbdesc_last,
657 sizeof(struct ospf6_dbdesc))) {
658 /* Duplicated DatabaseDescription is dropped by master
659 */
660 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
661 zlog_debug(
662 "Duplicated dbdesc discarded by Master, ignore");
663 return;
664 }
665
666 if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)) {
667 zlog_warn(
668 "DbDesc recv: Master/Slave bit mismatch Nbr %s",
669 on->name);
670 event_add_event(master, seqnumber_mismatch, on, 0,
671 NULL);
672 return;
673 }
674
675 if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) {
676 zlog_warn("DbDesc recv: Initialize bit mismatch Nbr %s",
677 on->name);
678 event_add_event(master, seqnumber_mismatch, on, 0,
679 NULL);
680 return;
681 }
682
683 if (memcmp(on->options, dbdesc->options, sizeof(on->options))) {
684 zlog_warn("DbDesc recv: Option field mismatch Nbr %s",
685 on->name);
686 event_add_event(master, seqnumber_mismatch, on, 0,
687 NULL);
688 return;
689 }
690
691 if (ntohl(dbdesc->seqnum) != on->dbdesc_seqnum) {
692 zlog_warn(
693 "DbDesc recv: Sequence number mismatch Nbr %s (received %#lx, %#lx expected)",
694 on->name, (unsigned long)ntohl(dbdesc->seqnum),
695 (unsigned long)on->dbdesc_seqnum);
696 event_add_event(master, seqnumber_mismatch, on, 0,
697 NULL);
698 return;
699 }
700 break;
701
702 case OSPF6_NEIGHBOR_LOADING:
703 case OSPF6_NEIGHBOR_FULL:
704 if (!memcmp(dbdesc, &on->dbdesc_last,
705 sizeof(struct ospf6_dbdesc))) {
706 /* Duplicated DatabaseDescription is dropped by master
707 */
708 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
709 zlog_debug(
710 "Duplicated dbdesc discarded by Master, ignore");
711 return;
712 }
713
714 zlog_warn(
715 "DbDesc recv: Not duplicate dbdesc in state %s Nbr %s",
716 ospf6_neighbor_state_str[on->state], on->name);
717 event_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 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
735 zlog_debug("%s", his->name);
736
737 switch (OSPF6_LSA_SCOPE(his->header->type)) {
738 case OSPF6_SCOPE_LINKLOCAL:
739 lsdb = on->ospf6_if->lsdb;
740 break;
741 case OSPF6_SCOPE_AREA:
742 lsdb = on->ospf6_if->area->lsdb;
743 break;
744 case OSPF6_SCOPE_AS:
745 lsdb = on->ospf6_if->area->ospf6->lsdb;
746 break;
747 case OSPF6_SCOPE_RESERVED:
748 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
749 zlog_debug("Ignoring LSA of reserved scope");
750 ospf6_lsa_delete(his);
751 continue;
752 }
753
754 if (ntohs(his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL
755 && (IS_AREA_STUB(on->ospf6_if->area)
756 || IS_AREA_NSSA(on->ospf6_if->area))) {
757 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
758 zlog_debug(
759 "SeqNumMismatch (E-bit mismatch), discard");
760 ospf6_lsa_delete(his);
761 event_add_event(master, seqnumber_mismatch, on, 0,
762 NULL);
763 return;
764 }
765
766 mine = ospf6_lsdb_lookup(his->header->type, his->header->id,
767 his->header->adv_router, lsdb);
768 if (mine == NULL) {
769 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
770 zlog_debug("Add request (No database copy)");
771 ospf6_lsdb_add(ospf6_lsa_copy(his), on->request_list);
772 } else if (ospf6_lsa_compare(his, mine) < 0) {
773 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
774 zlog_debug("Add request (Received MoreRecent)");
775 ospf6_lsdb_add(ospf6_lsa_copy(his), on->request_list);
776 } else {
777 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
778 zlog_debug("Discard (Existing MoreRecent)");
779 }
780 ospf6_lsa_delete(his);
781 }
782
783 assert(p == OSPF6_MESSAGE_END(oh));
784
785 /* Increment sequence number */
786 on->dbdesc_seqnum++;
787
788 /* schedule send lsreq */
789 if (on->request_list->count)
790 event_add_event(master, ospf6_lsreq_send, on, 0,
791 &on->thread_send_lsreq);
792
793 EVENT_OFF(on->thread_send_dbdesc);
794
795 /* More bit check */
796 if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT)
797 && !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT))
798 event_add_event(master, exchange_done, on, 0,
799 &on->thread_exchange_done);
800 else {
801 event_add_event(master, ospf6_dbdesc_send_newone, on, 0,
802 &on->thread_send_dbdesc);
803 }
804
805 /* save last received dbdesc */
806 memcpy(&on->dbdesc_last, dbdesc, sizeof(struct ospf6_dbdesc));
807 }
808
809 static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
810 struct ospf6_neighbor *on)
811 {
812 struct ospf6_dbdesc *dbdesc;
813 char *p;
814
815 dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh
816 + sizeof(struct ospf6_header));
817
818 if (on->state < OSPF6_NEIGHBOR_INIT) {
819 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
820 zlog_debug("Neighbor state less than Init, ignore");
821 return;
822 }
823
824 switch (on->state) {
825 case OSPF6_NEIGHBOR_TWOWAY:
826 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
827 zlog_debug("Neighbor state is 2-Way, ignore");
828 return;
829
830 case OSPF6_NEIGHBOR_INIT:
831 event_execute(master, twoway_received, on, 0);
832 if (on->state != OSPF6_NEIGHBOR_EXSTART) {
833 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
834 zlog_debug(
835 "Neighbor state is not ExStart, ignore");
836 return;
837 }
838 /* else fall through to ExStart */
839 /* fallthru */
840 case OSPF6_NEIGHBOR_EXSTART:
841 /* If the neighbor is Master, act as Slave. Schedule
842 negotiation_done
843 and process LSA Headers. Otherwise, ignore this message */
844 if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)
845 && CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT)
846 && CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)
847 && ntohs(oh->length)
848 == sizeof(struct ospf6_header)
849 + sizeof(struct ospf6_dbdesc)) {
850 /* set the master/slave bit to slave */
851 UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
852
853 /* set the DD sequence number to one specified by master
854 */
855 on->dbdesc_seqnum = ntohl(dbdesc->seqnum);
856
857 /* schedule NegotiationDone */
858 event_execute(master, negotiation_done, on, 0);
859
860 /* Record neighbor options */
861 memcpy(on->options, dbdesc->options,
862 sizeof(on->options));
863 } else {
864 zlog_warn("VRF %s: Nbr %s Negotiation failed",
865 on->ospf6_if->interface->vrf->name, on->name);
866 return;
867 }
868 break;
869
870 case OSPF6_NEIGHBOR_EXCHANGE:
871 if (!memcmp(dbdesc, &on->dbdesc_last,
872 sizeof(struct ospf6_dbdesc))) {
873 /* Duplicated DatabaseDescription causes slave to
874 * retransmit */
875 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
876 zlog_debug(
877 "Duplicated dbdesc causes retransmit");
878 EVENT_OFF(on->thread_send_dbdesc);
879 event_add_event(master, ospf6_dbdesc_send, on, 0,
880 &on->thread_send_dbdesc);
881 return;
882 }
883
884 if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)) {
885 zlog_warn(
886 "DbDesc slave recv: Master/Slave bit mismatch Nbr %s",
887 on->name);
888 event_add_event(master, seqnumber_mismatch, on, 0,
889 NULL);
890 return;
891 }
892
893 if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) {
894 zlog_warn(
895 "DbDesc slave recv: Initialize bit mismatch Nbr %s",
896 on->name);
897 event_add_event(master, seqnumber_mismatch, on, 0,
898 NULL);
899 return;
900 }
901
902 if (memcmp(on->options, dbdesc->options, sizeof(on->options))) {
903 zlog_warn(
904 "DbDesc slave recv: Option field mismatch Nbr %s",
905 on->name);
906 event_add_event(master, seqnumber_mismatch, on, 0,
907 NULL);
908 return;
909 }
910
911 if (ntohl(dbdesc->seqnum) != on->dbdesc_seqnum + 1) {
912 zlog_warn(
913 "DbDesc slave recv: Sequence number mismatch Nbr %s (received %#lx, %#lx expected)",
914 on->name, (unsigned long)ntohl(dbdesc->seqnum),
915 (unsigned long)on->dbdesc_seqnum + 1);
916 event_add_event(master, seqnumber_mismatch, on, 0,
917 NULL);
918 return;
919 }
920 break;
921
922 case OSPF6_NEIGHBOR_LOADING:
923 case OSPF6_NEIGHBOR_FULL:
924 if (!memcmp(dbdesc, &on->dbdesc_last,
925 sizeof(struct ospf6_dbdesc))) {
926 /* Duplicated DatabaseDescription causes slave to
927 * retransmit */
928 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
929 zlog_debug(
930 "Duplicated dbdesc causes retransmit");
931 EVENT_OFF(on->thread_send_dbdesc);
932 event_add_event(master, ospf6_dbdesc_send, on, 0,
933 &on->thread_send_dbdesc);
934 return;
935 }
936
937 zlog_warn(
938 "DbDesc slave recv: Not duplicate dbdesc in state %s Nbr %s",
939 ospf6_neighbor_state_str[on->state], on->name);
940 event_add_event(master, seqnumber_mismatch, on, 0, NULL);
941 return;
942
943 default:
944 assert(0);
945 break;
946 }
947
948 /* Process LSA headers */
949 for (p = (char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc));
950 p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh);
951 p += sizeof(struct ospf6_lsa_header)) {
952 struct ospf6_lsa *his, *mine;
953 struct ospf6_lsdb *lsdb = NULL;
954
955 his = ospf6_lsa_create_headeronly((struct ospf6_lsa_header *)p);
956
957 switch (OSPF6_LSA_SCOPE(his->header->type)) {
958 case OSPF6_SCOPE_LINKLOCAL:
959 lsdb = on->ospf6_if->lsdb;
960 break;
961 case OSPF6_SCOPE_AREA:
962 lsdb = on->ospf6_if->area->lsdb;
963 break;
964 case OSPF6_SCOPE_AS:
965 lsdb = on->ospf6_if->area->ospf6->lsdb;
966 break;
967 case OSPF6_SCOPE_RESERVED:
968 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
969 zlog_debug("Ignoring LSA of reserved scope");
970 ospf6_lsa_delete(his);
971 continue;
972 }
973
974 if (OSPF6_LSA_SCOPE(his->header->type) == OSPF6_SCOPE_AS
975 && (IS_AREA_STUB(on->ospf6_if->area)
976 || IS_AREA_NSSA(on->ospf6_if->area))) {
977 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
978 zlog_debug("E-bit mismatch with LSA Headers");
979 ospf6_lsa_delete(his);
980 event_add_event(master, seqnumber_mismatch, on, 0,
981 NULL);
982 return;
983 }
984
985 mine = ospf6_lsdb_lookup(his->header->type, his->header->id,
986 his->header->adv_router, lsdb);
987 if (mine == NULL || ospf6_lsa_compare(his, mine) < 0) {
988 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
989 zlog_debug("Add request-list: %s", his->name);
990 ospf6_lsdb_add(ospf6_lsa_copy(his), on->request_list);
991 }
992 ospf6_lsa_delete(his);
993 }
994
995 assert(p == OSPF6_MESSAGE_END(oh));
996
997 /* Set sequence number to Master's */
998 on->dbdesc_seqnum = ntohl(dbdesc->seqnum);
999
1000 /* schedule send lsreq */
1001 if (on->request_list->count)
1002 event_add_event(master, ospf6_lsreq_send, on, 0,
1003 &on->thread_send_lsreq);
1004
1005 EVENT_OFF(on->thread_send_dbdesc);
1006 event_add_event(master, ospf6_dbdesc_send_newone, on, 0,
1007 &on->thread_send_dbdesc);
1008
1009 /* save last received dbdesc */
1010 memcpy(&on->dbdesc_last, dbdesc, sizeof(struct ospf6_dbdesc));
1011 }
1012
1013 static void ospf6_dbdesc_recv(struct in6_addr *src, struct in6_addr *dst,
1014 struct ospf6_interface *oi,
1015 struct ospf6_header *oh)
1016 {
1017 struct ospf6_neighbor *on;
1018 struct ospf6_dbdesc *dbdesc;
1019
1020 on = ospf6_neighbor_lookup(oh->router_id, oi);
1021 if (on == NULL) {
1022 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
1023 zlog_debug("Neighbor not found, ignore");
1024 return;
1025 }
1026
1027 dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh
1028 + sizeof(struct ospf6_header));
1029
1030 if (((OSPF6_OPT_ISSET_EXT(dbdesc->options, OSPF6_OPT_AT) ==
1031 OSPF6_OPT_AT) &&
1032 (oi->at_data.flags == 0)) ||
1033 ((OSPF6_OPT_ISSET_EXT(dbdesc->options, OSPF6_OPT_AT) !=
1034 OSPF6_OPT_AT) &&
1035 (oi->at_data.flags != 0))) {
1036 if (IS_OSPF6_DEBUG_AUTH_RX)
1037 zlog_warn(
1038 "VRF %s: IF %s AT-bit mismatch in dbdesc packet",
1039 oi->interface->vrf->name, oi->interface->name);
1040 oi->at_data.rx_drop++;
1041 return;
1042 }
1043
1044 /* Interface MTU check */
1045 if (!oi->mtu_ignore && ntohs(dbdesc->ifmtu) != oi->ifmtu) {
1046 zlog_warn("VRF %s: I/F %s MTU mismatch (my %d rcvd %d)",
1047 oi->interface->vrf->name, oi->interface->name,
1048 oi->ifmtu, ntohs(dbdesc->ifmtu));
1049 return;
1050 }
1051
1052 if (dbdesc->reserved1 || dbdesc->reserved2) {
1053 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
1054 zlog_debug(
1055 "Non-0 reserved field in %s's DbDesc, correct",
1056 on->name);
1057 dbdesc->reserved1 = 0;
1058 dbdesc->reserved2 = 0;
1059 }
1060
1061 oi->db_desc_in++;
1062
1063 if (ntohl(oh->router_id) < ntohl(oi->area->ospf6->router_id))
1064 ospf6_dbdesc_recv_master(oh, on);
1065 else if (ntohl(oi->area->ospf6->router_id) < ntohl(oh->router_id))
1066 ospf6_dbdesc_recv_slave(oh, on);
1067 else {
1068 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
1069 zlog_debug("Can't decide which is master, ignore");
1070 }
1071 }
1072
1073 static void ospf6_lsreq_recv(struct in6_addr *src, struct in6_addr *dst,
1074 struct ospf6_interface *oi,
1075 struct ospf6_header *oh)
1076 {
1077 struct ospf6_neighbor *on;
1078 char *p;
1079 struct ospf6_lsreq_entry *e;
1080 struct ospf6_lsdb *lsdb = NULL;
1081 struct ospf6_lsa *lsa;
1082
1083 on = ospf6_neighbor_lookup(oh->router_id, oi);
1084 if (on == NULL) {
1085 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
1086 zlog_debug("Neighbor not found, ignore");
1087 return;
1088 }
1089
1090 if (on->state != OSPF6_NEIGHBOR_EXCHANGE
1091 && on->state != OSPF6_NEIGHBOR_LOADING
1092 && on->state != OSPF6_NEIGHBOR_FULL) {
1093 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
1094 zlog_debug("Neighbor state less than Exchange, ignore");
1095 return;
1096 }
1097
1098 oi->ls_req_in++;
1099
1100 /* Process each request */
1101 for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header));
1102 p + sizeof(struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END(oh);
1103 p += sizeof(struct ospf6_lsreq_entry)) {
1104 e = (struct ospf6_lsreq_entry *)p;
1105
1106 switch (OSPF6_LSA_SCOPE(e->type)) {
1107 case OSPF6_SCOPE_LINKLOCAL:
1108 lsdb = on->ospf6_if->lsdb;
1109 break;
1110 case OSPF6_SCOPE_AREA:
1111 lsdb = on->ospf6_if->area->lsdb;
1112 break;
1113 case OSPF6_SCOPE_AS:
1114 lsdb = on->ospf6_if->area->ospf6->lsdb;
1115 break;
1116 default:
1117 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
1118 zlog_debug("Ignoring LSA of reserved scope");
1119 continue;
1120 }
1121
1122 /* Find database copy */
1123 lsa = ospf6_lsdb_lookup(e->type, e->id, e->adv_router, lsdb);
1124 if (lsa == NULL) {
1125 zlog_warn(
1126 "Can't find requested lsa [%s Id:%pI4 Adv:%pI4] send badLSReq",
1127 ospf6_lstype_name(e->type), &e->id,
1128 &e->adv_router);
1129 event_add_event(master, bad_lsreq, on, 0, NULL);
1130 return;
1131 }
1132
1133 ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->lsupdate_list);
1134 }
1135
1136 assert(p == OSPF6_MESSAGE_END(oh));
1137
1138 /* schedule send lsupdate */
1139 EVENT_OFF(on->thread_send_lsupdate);
1140 event_add_event(master, ospf6_lsupdate_send_neighbor, on, 0,
1141 &on->thread_send_lsupdate);
1142 }
1143
1144 /* Verify, that the specified memory area contains exactly N valid IPv6
1145 prefixes as specified by RFC5340, A.4.1. */
1146 static unsigned ospf6_prefixes_examin(
1147 struct ospf6_prefix *current, /* start of buffer */
1148 unsigned length,
1149 const uint32_t req_num_pfxs /* always compared with the actual number
1150 of prefixes */
1151 )
1152 {
1153 uint8_t requested_pfx_bytes;
1154 uint32_t real_num_pfxs = 0;
1155
1156 while (length) {
1157 if (length < OSPF6_PREFIX_MIN_SIZE) {
1158 zlog_warn("%s: undersized IPv6 prefix header",
1159 __func__);
1160 return MSG_NG;
1161 }
1162 /* safe to look deeper */
1163 if (current->prefix_length > IPV6_MAX_BITLEN) {
1164 zlog_warn("%s: invalid PrefixLength (%u bits)",
1165 __func__, current->prefix_length);
1166 return MSG_NG;
1167 }
1168 /* covers both fixed- and variable-sized fields */
1169 requested_pfx_bytes =
1170 OSPF6_PREFIX_MIN_SIZE
1171 + OSPF6_PREFIX_SPACE(current->prefix_length);
1172 if (requested_pfx_bytes > length) {
1173 zlog_warn("%s: undersized IPv6 prefix", __func__);
1174 return MSG_NG;
1175 }
1176 /* next prefix */
1177 length -= requested_pfx_bytes;
1178 current = (struct ospf6_prefix *)((caddr_t)current
1179 + requested_pfx_bytes);
1180 real_num_pfxs++;
1181 }
1182 if (real_num_pfxs != req_num_pfxs) {
1183 zlog_warn(
1184 "%s: IPv6 prefix number mismatch (%u required, %u real)",
1185 __func__, req_num_pfxs, real_num_pfxs);
1186 return MSG_NG;
1187 }
1188 return MSG_OK;
1189 }
1190
1191 /* Verify an LSA to have a valid length and dispatch further (where
1192 appropriate) to check if the contents, including nested IPv6 prefixes,
1193 is properly sized/aligned within the LSA. Note that this function gets
1194 LSA type in network byte order, uses in host byte order and passes to
1195 ospf6_lstype_name() in network byte order again. */
1196 static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah,
1197 const uint16_t lsalen,
1198 const uint8_t headeronly)
1199 {
1200 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1201 struct ospf6_as_external_lsa *as_external_lsa;
1202 struct ospf6_link_lsa *link_lsa;
1203 unsigned exp_length;
1204 uint8_t ltindex;
1205 uint16_t lsatype;
1206
1207 /* In case an additional minimum length constraint is defined for
1208 current
1209 LSA type, make sure that this constraint is met. */
1210 lsatype = ntohs(lsah->type);
1211 ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK;
1212 if (ltindex < OSPF6_LSTYPE_SIZE && ospf6_lsa_minlen[ltindex]
1213 && lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE) {
1214 zlog_warn("%s: undersized (%u B) LSA", __func__, lsalen);
1215 return MSG_NG;
1216 }
1217 switch (lsatype) {
1218 case OSPF6_LSTYPE_ROUTER:
1219 /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes
1220 followed
1221 by N>=0 interface descriptions. */
1222 if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE)
1223 % OSPF6_ROUTER_LSDESC_FIX_SIZE) {
1224 zlog_warn(
1225 "%s: Router LSA interface description alignment error",
1226 __func__);
1227 return MSG_NG;
1228 }
1229 break;
1230 case OSPF6_LSTYPE_NETWORK:
1231 /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes
1232 followed by N>=0 attached router descriptions. */
1233 if ((lsalen - OSPF6_LSA_HEADER_SIZE
1234 - OSPF6_NETWORK_LSA_MIN_SIZE)
1235 % OSPF6_NETWORK_LSDESC_FIX_SIZE) {
1236 zlog_warn(
1237 "%s: Network LSA router description alignment error",
1238 __func__);
1239 return MSG_NG;
1240 }
1241 break;
1242 case OSPF6_LSTYPE_INTER_PREFIX:
1243 /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE
1244 bytes
1245 followed by 3-4 fields of a single IPv6 prefix. */
1246 if (headeronly)
1247 break;
1248 return ospf6_prefixes_examin(
1249 (struct ospf6_prefix
1250 *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE
1251 + OSPF6_INTER_PREFIX_LSA_MIN_SIZE),
1252 lsalen - OSPF6_LSA_HEADER_SIZE
1253 - OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
1254 1);
1255 case OSPF6_LSTYPE_INTER_ROUTER:
1256 /* RFC5340 A.4.6, fixed-size LSA. */
1257 if (lsalen
1258 > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE) {
1259 zlog_warn("%s: Inter Router LSA oversized (%u B) LSA",
1260 __func__, lsalen);
1261 return MSG_NG;
1262 }
1263 break;
1264 case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */
1265 case OSPF6_LSTYPE_TYPE_7:
1266 /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
1267 bytes
1268 followed by 3-4 fields of IPv6 prefix and 3 conditional LSA
1269 fields:
1270 16 bytes of forwarding address, 4 bytes of external route
1271 tag,
1272 4 bytes of referenced link state ID. */
1273 if (headeronly)
1274 break;
1275 as_external_lsa =
1276 (struct ospf6_as_external_lsa
1277 *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE);
1278 exp_length =
1279 OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE;
1280 /* To find out if the last optional field (Referenced Link State
1281 ID) is
1282 assumed in this LSA, we need to access fixed fields of the
1283 IPv6
1284 prefix before ospf6_prefix_examin() confirms its sizing. */
1285 if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen) {
1286 zlog_warn(
1287 "%s: AS External undersized (%u B) LSA header",
1288 __func__, lsalen);
1289 return MSG_NG;
1290 }
1291 /* forwarding address */
1292 if (CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
1293 exp_length += 16;
1294 /* external route tag */
1295 if (CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
1296 exp_length += 4;
1297 /* referenced link state ID */
1298 if (as_external_lsa->prefix.u._prefix_referenced_lstype)
1299 exp_length += 4;
1300 /* All the fixed-size fields (mandatory and optional) must fit.
1301 I.e.,
1302 this check does not include any IPv6 prefix fields. */
1303 if (exp_length > lsalen) {
1304 zlog_warn(
1305 "%s: AS External undersized (%u B) LSA header",
1306 __func__, lsalen);
1307 return MSG_NG;
1308 }
1309 /* The last call completely covers the remainder (IPv6 prefix).
1310 */
1311 return ospf6_prefixes_examin(
1312 (struct ospf6_prefix
1313 *)((caddr_t)as_external_lsa
1314 + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE),
1315 lsalen - exp_length, 1);
1316 case OSPF6_LSTYPE_LINK:
1317 /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes
1318 followed
1319 by N>=0 IPv6 prefix blocks (with N declared beforehand). */
1320 if (headeronly)
1321 break;
1322 link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsah
1323 + OSPF6_LSA_HEADER_SIZE);
1324 return ospf6_prefixes_examin(
1325 (struct ospf6_prefix *)((caddr_t)link_lsa
1326 + OSPF6_LINK_LSA_MIN_SIZE),
1327 lsalen - OSPF6_LSA_HEADER_SIZE
1328 - OSPF6_LINK_LSA_MIN_SIZE,
1329 ntohl(link_lsa->prefix_num) /* 32 bits */
1330 );
1331 case OSPF6_LSTYPE_INTRA_PREFIX:
1332 /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
1333 bytes
1334 followed by N>=0 IPv6 prefixes (with N declared beforehand).
1335 */
1336 if (headeronly)
1337 break;
1338 intra_prefix_lsa =
1339 (struct ospf6_intra_prefix_lsa
1340 *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE);
1341 return ospf6_prefixes_examin(
1342 (struct ospf6_prefix
1343 *)((caddr_t)intra_prefix_lsa
1344 + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE),
1345 lsalen - OSPF6_LSA_HEADER_SIZE
1346 - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE,
1347 ntohs(intra_prefix_lsa->prefix_num) /* 16 bits */
1348 );
1349 case OSPF6_LSTYPE_GRACE_LSA:
1350 if (lsalen < OSPF6_LSA_HEADER_SIZE + GRACE_PERIOD_TLV_SIZE
1351 + GRACE_RESTART_REASON_TLV_SIZE) {
1352 if (IS_DEBUG_OSPF6_GR)
1353 zlog_debug("%s: Undersized GraceLSA.",
1354 __func__);
1355 return MSG_NG;
1356 }
1357 }
1358 /* No additional validation is possible for unknown LSA types, which are
1359 themselves valid in OPSFv3, hence the default decision is to accept.
1360 */
1361 return MSG_OK;
1362 }
1363
1364 /* Verify if the provided input buffer is a valid sequence of LSAs. This
1365 includes verification of LSA blocks length/alignment and dispatching
1366 of deeper-level checks. */
1367 static unsigned
1368 ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */
1369 size_t length, const uint8_t headeronly,
1370 /* When declared_num_lsas is not 0, compare it to the real
1371 number of LSAs
1372 and treat the difference as an error. */
1373 const uint32_t declared_num_lsas)
1374 {
1375 uint32_t counted_lsas = 0;
1376
1377 while (length) {
1378 uint16_t lsalen;
1379 if (length < OSPF6_LSA_HEADER_SIZE) {
1380 zlog_warn(
1381 "%s: undersized (%zu B) trailing (#%u) LSA header",
1382 __func__, length, counted_lsas);
1383 return MSG_NG;
1384 }
1385 /* save on ntohs() calls here and in the LSA validator */
1386 lsalen = OSPF6_LSA_SIZE(lsah);
1387 if (lsalen < OSPF6_LSA_HEADER_SIZE) {
1388 zlog_warn(
1389 "%s: malformed LSA header #%u, declared length is %u B",
1390 __func__, counted_lsas, lsalen);
1391 return MSG_NG;
1392 }
1393 if (headeronly) {
1394 /* less checks here and in ospf6_lsa_examin() */
1395 if (MSG_OK != ospf6_lsa_examin(lsah, lsalen, 1)) {
1396 zlog_warn(
1397 "%s: anomaly in header-only %s LSA #%u",
1398 __func__, ospf6_lstype_name(lsah->type),
1399 counted_lsas);
1400 return MSG_NG;
1401 }
1402 lsah = (struct ospf6_lsa_header
1403 *)((caddr_t)lsah
1404 + OSPF6_LSA_HEADER_SIZE);
1405 length -= OSPF6_LSA_HEADER_SIZE;
1406 } else {
1407 /* make sure the input buffer is deep enough before
1408 * further checks */
1409 if (lsalen > length) {
1410 zlog_warn(
1411 "%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B",
1412 __func__, ospf6_lstype_name(lsah->type),
1413 counted_lsas, lsalen, length);
1414 return MSG_NG;
1415 }
1416 if (MSG_OK != ospf6_lsa_examin(lsah, lsalen, 0)) {
1417 zlog_warn("%s: anomaly in %s LSA #%u", __func__,
1418 ospf6_lstype_name(lsah->type),
1419 counted_lsas);
1420 return MSG_NG;
1421 }
1422 lsah = (struct ospf6_lsa_header *)((caddr_t)lsah
1423 + lsalen);
1424 length -= lsalen;
1425 }
1426 counted_lsas++;
1427 }
1428
1429 if (declared_num_lsas && counted_lsas != declared_num_lsas) {
1430 zlog_warn("%s: #LSAs declared (%u) does not match actual (%u)",
1431 __func__, declared_num_lsas, counted_lsas);
1432 return MSG_NG;
1433 }
1434 return MSG_OK;
1435 }
1436
1437 /* Verify a complete OSPF packet for proper sizing/alignment. */
1438 static unsigned ospf6_packet_examin(struct ospf6_header *oh,
1439 const unsigned bytesonwire)
1440 {
1441 struct ospf6_lsupdate *lsupd;
1442 unsigned test;
1443
1444 /* length, 1st approximation */
1445 if (bytesonwire < OSPF6_HEADER_SIZE) {
1446 zlog_warn("%s: undersized (%u B) packet", __func__,
1447 bytesonwire);
1448 return MSG_NG;
1449 }
1450
1451 /* Now it is safe to access header fields. */
1452 if (bytesonwire != ntohs(oh->length)) {
1453 zlog_warn("%s: %s packet length error (%u real, %u declared)",
1454 __func__, ospf6_message_type(oh->type), bytesonwire,
1455 ntohs(oh->length));
1456 return MSG_NG;
1457 }
1458
1459 /* version check */
1460 if (oh->version != OSPFV3_VERSION) {
1461 zlog_warn("%s: invalid (%u) protocol version", __func__,
1462 oh->version);
1463 return MSG_NG;
1464 }
1465 /* length, 2nd approximation */
1466 if (oh->type < OSPF6_MESSAGE_TYPE_ALL && ospf6_packet_minlen[oh->type]
1467 && bytesonwire
1468 < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type]) {
1469 zlog_warn("%s: undersized (%u B) %s packet", __func__,
1470 bytesonwire, ospf6_message_type(oh->type));
1471 return MSG_NG;
1472 }
1473 /* type-specific deeper validation */
1474 switch (oh->type) {
1475 case OSPF6_MESSAGE_TYPE_HELLO:
1476 /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes
1477 followed
1478 by N>=0 router-IDs. */
1479 if (0
1480 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE)
1481 % 4)
1482 return MSG_OK;
1483 zlog_warn("%s: alignment error in %s packet", __func__,
1484 ospf6_message_type(oh->type));
1485 return MSG_NG;
1486 case OSPF6_MESSAGE_TYPE_DBDESC:
1487 /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes
1488 followed
1489 by N>=0 header-only LSAs. */
1490 test = ospf6_lsaseq_examin(
1491 (struct ospf6_lsa_header *)((caddr_t)oh
1492 + OSPF6_HEADER_SIZE
1493 + OSPF6_DB_DESC_MIN_SIZE),
1494 bytesonwire - OSPF6_HEADER_SIZE
1495 - OSPF6_DB_DESC_MIN_SIZE,
1496 1, 0);
1497 break;
1498 case OSPF6_MESSAGE_TYPE_LSREQ:
1499 /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */
1500 if (0
1501 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE)
1502 % OSPF6_LSREQ_LSDESC_FIX_SIZE)
1503 return MSG_OK;
1504 zlog_warn("%s: alignment error in %s packet", __func__,
1505 ospf6_message_type(oh->type));
1506 return MSG_NG;
1507 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1508 /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes
1509 followed
1510 by N>=0 full LSAs (with N declared beforehand). */
1511 lsupd = (struct ospf6_lsupdate *)((caddr_t)oh
1512 + OSPF6_HEADER_SIZE);
1513 test = ospf6_lsaseq_examin(
1514 (struct ospf6_lsa_header *)((caddr_t)lsupd
1515 + OSPF6_LS_UPD_MIN_SIZE),
1516 bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE,
1517 0, ntohl(lsupd->lsa_number) /* 32 bits */
1518 );
1519 break;
1520 case OSPF6_MESSAGE_TYPE_LSACK:
1521 /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */
1522 test = ospf6_lsaseq_examin(
1523 (struct ospf6_lsa_header *)((caddr_t)oh
1524 + OSPF6_HEADER_SIZE
1525 + OSPF6_LS_ACK_MIN_SIZE),
1526 bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE,
1527 1, 0);
1528 break;
1529 default:
1530 zlog_warn("%s: invalid (%u) message type", __func__, oh->type);
1531 return MSG_NG;
1532 }
1533 if (test != MSG_OK)
1534 zlog_warn("%s: anomaly in %s packet", __func__,
1535 ospf6_message_type(oh->type));
1536 return test;
1537 }
1538
1539 /* Verify particular fields of otherwise correct received OSPF packet to
1540 meet the requirements of RFC. */
1541 static int ospf6_rxpacket_examin(struct ospf6_interface *oi,
1542 struct ospf6_header *oh,
1543 const unsigned bytesonwire)
1544 {
1545 struct ospf6_neighbor *on;
1546
1547 if (MSG_OK != ospf6_packet_examin(oh, bytesonwire))
1548 return MSG_NG;
1549
1550 on = ospf6_neighbor_lookup(oh->router_id, oi);
1551
1552 /* Area-ID check */
1553 if (oh->area_id != oi->area->area_id) {
1554 if (oh->area_id == OSPF_AREA_BACKBONE)
1555 zlog_warn(
1556 "VRF %s: I/F %s (%s, Router-ID: %pI4) Message may be via Virtual Link: not supported",
1557 oi->interface->vrf->name, oi->interface->name,
1558 on ? on->name : "null", &oh->router_id);
1559 else
1560 zlog_warn(
1561 "VRF %s: I/F %s (%s, Router-ID: %pI4) Area-ID mismatch (my %pI4, rcvd %pI4)",
1562 oi->interface->vrf->name, oi->interface->name,
1563 on ? on->name : "null", &oh->router_id,
1564 &oi->area->area_id, &oh->area_id);
1565 return MSG_NG;
1566 }
1567
1568 /* Instance-ID check */
1569 if (oh->instance_id != oi->instance_id) {
1570 zlog_warn(
1571 "VRF %s: I/F %s (%s, Router-ID: %pI4) Instance-ID mismatch (my %u, rcvd %u)",
1572 oi->interface->vrf->name, oi->interface->name,
1573 on ? on->name : "null", &oh->router_id, oi->instance_id,
1574 oh->instance_id);
1575 return MSG_NG;
1576 }
1577
1578 /* Router-ID check */
1579 if (oh->router_id == oi->area->ospf6->router_id) {
1580 zlog_warn("VRF %s: I/F %s Duplicate Router-ID (%pI4)",
1581 oi->interface->vrf->name, oi->interface->name,
1582 &oh->router_id);
1583 return MSG_NG;
1584 }
1585 return MSG_OK;
1586 }
1587
1588 static void ospf6_lsupdate_recv(struct in6_addr *src, struct in6_addr *dst,
1589 struct ospf6_interface *oi,
1590 struct ospf6_header *oh)
1591 {
1592 struct ospf6_neighbor *on;
1593 struct ospf6_lsupdate *lsupdate;
1594 char *p;
1595
1596 on = ospf6_neighbor_lookup(oh->router_id, oi);
1597 if (on == NULL) {
1598 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
1599 zlog_debug("Neighbor not found, ignore");
1600 return;
1601 }
1602
1603 if (on->state != OSPF6_NEIGHBOR_EXCHANGE
1604 && on->state != OSPF6_NEIGHBOR_LOADING
1605 && on->state != OSPF6_NEIGHBOR_FULL) {
1606 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
1607 zlog_debug("Neighbor state less than Exchange, ignore");
1608 return;
1609 }
1610
1611 lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh
1612 + sizeof(struct ospf6_header));
1613
1614 oi->ls_upd_in++;
1615
1616 /* Process LSAs */
1617 for (p = (char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate));
1618 p < OSPF6_MESSAGE_END(oh)
1619 && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh);
1620 p += OSPF6_LSA_SIZE(p)) {
1621 ospf6_receive_lsa(on, (struct ospf6_lsa_header *)p);
1622 }
1623
1624 assert(p == OSPF6_MESSAGE_END(oh));
1625 }
1626
1627 static void ospf6_lsack_recv(struct in6_addr *src, struct in6_addr *dst,
1628 struct ospf6_interface *oi,
1629 struct ospf6_header *oh)
1630 {
1631 struct ospf6_neighbor *on;
1632 char *p;
1633 struct ospf6_lsa *his, *mine;
1634 struct ospf6_lsdb *lsdb = NULL;
1635
1636 assert(oh->type == OSPF6_MESSAGE_TYPE_LSACK);
1637
1638 on = ospf6_neighbor_lookup(oh->router_id, oi);
1639 if (on == NULL) {
1640 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
1641 zlog_debug("Neighbor not found, ignore");
1642 return;
1643 }
1644
1645 if (on->state != OSPF6_NEIGHBOR_EXCHANGE
1646 && on->state != OSPF6_NEIGHBOR_LOADING
1647 && on->state != OSPF6_NEIGHBOR_FULL) {
1648 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
1649 zlog_debug("Neighbor state less than Exchange, ignore");
1650 return;
1651 }
1652
1653 oi->ls_ack_in++;
1654
1655 for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header));
1656 p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh);
1657 p += sizeof(struct ospf6_lsa_header)) {
1658 his = ospf6_lsa_create_headeronly((struct ospf6_lsa_header *)p);
1659
1660 switch (OSPF6_LSA_SCOPE(his->header->type)) {
1661 case OSPF6_SCOPE_LINKLOCAL:
1662 lsdb = on->ospf6_if->lsdb;
1663 break;
1664 case OSPF6_SCOPE_AREA:
1665 lsdb = on->ospf6_if->area->lsdb;
1666 break;
1667 case OSPF6_SCOPE_AS:
1668 lsdb = on->ospf6_if->area->ospf6->lsdb;
1669 break;
1670 case OSPF6_SCOPE_RESERVED:
1671 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
1672 zlog_debug("Ignoring LSA of reserved scope");
1673 ospf6_lsa_delete(his);
1674 continue;
1675 }
1676
1677 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
1678 zlog_debug("%s acknowledged by %s", his->name,
1679 on->name);
1680
1681 /* Find database copy */
1682 mine = ospf6_lsdb_lookup(his->header->type, his->header->id,
1683 his->header->adv_router, lsdb);
1684 if (mine == NULL) {
1685 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
1686 zlog_debug("No database copy");
1687 ospf6_lsa_delete(his);
1688 continue;
1689 }
1690
1691 /* Check if the LSA is on his retrans-list */
1692 mine = ospf6_lsdb_lookup(his->header->type, his->header->id,
1693 his->header->adv_router,
1694 on->retrans_list);
1695 if (mine == NULL) {
1696 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
1697 zlog_debug("Not on %s's retrans-list",
1698 on->name);
1699 ospf6_lsa_delete(his);
1700 continue;
1701 }
1702
1703 if (ospf6_lsa_compare(his, mine) != 0) {
1704 /* Log this questionable acknowledgement,
1705 and examine the next one. */
1706 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
1707 zlog_debug("Questionable acknowledgement");
1708 ospf6_lsa_delete(his);
1709 continue;
1710 }
1711
1712 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
1713 zlog_debug(
1714 "Acknowledged, remove from %s's retrans-list",
1715 on->name);
1716
1717 ospf6_decrement_retrans_count(mine);
1718 if (OSPF6_LSA_IS_MAXAGE(mine))
1719 ospf6_maxage_remove(on->ospf6_if->area->ospf6);
1720 ospf6_lsdb_remove(mine, on->retrans_list);
1721 ospf6_lsa_delete(his);
1722 }
1723
1724 assert(p == OSPF6_MESSAGE_END(oh));
1725 }
1726
1727 static uint8_t *recvbuf = NULL;
1728 static uint8_t *sendbuf = NULL;
1729 static unsigned int iobuflen = 0;
1730
1731 int ospf6_iobuf_size(unsigned int size)
1732 {
1733 /* NB: there was previously code here that tried to dynamically size
1734 * the buffer for whatever we see in MTU on interfaces. Which is
1735 * _unconditionally wrong_ - we can always receive fragmented IPv6
1736 * up to the regular 64k length limit. (No jumbograms, thankfully.)
1737 */
1738
1739 if (!iobuflen) {
1740 /* the + 128 is to have some runway at the end */
1741 size_t alloc_size = 65536 + 128;
1742
1743 assert(!recvbuf && !sendbuf);
1744
1745 recvbuf = XMALLOC(MTYPE_OSPF6_MESSAGE, alloc_size);
1746 sendbuf = XMALLOC(MTYPE_OSPF6_MESSAGE, alloc_size);
1747 iobuflen = alloc_size;
1748 }
1749
1750 return iobuflen;
1751 }
1752
1753 void ospf6_message_terminate(void)
1754 {
1755 XFREE(MTYPE_OSPF6_MESSAGE, recvbuf);
1756 XFREE(MTYPE_OSPF6_MESSAGE, sendbuf);
1757
1758 iobuflen = 0;
1759 }
1760
1761 enum ospf6_read_return_enum {
1762 OSPF6_READ_ERROR,
1763 OSPF6_READ_CONTINUE,
1764 };
1765
1766 static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6)
1767 {
1768 int len;
1769 struct in6_addr src, dst;
1770 ifindex_t ifindex;
1771 struct iovec iovector[2];
1772 struct ospf6_interface *oi;
1773 struct ospf6_header *oh;
1774 enum ospf6_auth_err ret = OSPF6_AUTH_PROCESS_NORMAL;
1775 uint32_t at_len = 0;
1776 uint32_t lls_len = 0;
1777
1778 /* initialize */
1779 memset(&src, 0, sizeof(src));
1780 memset(&dst, 0, sizeof(dst));
1781 ifindex = 0;
1782 iovector[0].iov_base = recvbuf;
1783 iovector[0].iov_len = iobuflen;
1784 iovector[1].iov_base = NULL;
1785 iovector[1].iov_len = 0;
1786
1787 /* receive message */
1788 len = ospf6_recvmsg(&src, &dst, &ifindex, iovector, sockfd);
1789 if (len < 0)
1790 return OSPF6_READ_ERROR;
1791
1792 if ((uint)len > iobuflen) {
1793 flog_err(EC_LIB_DEVELOPMENT, "Excess message read");
1794 return OSPF6_READ_ERROR;
1795 }
1796
1797 /* ensure some zeroes past the end, just as a security precaution */
1798 memset(recvbuf + len, 0, MIN(128, iobuflen - len));
1799
1800 oi = ospf6_interface_lookup_by_ifindex(ifindex, ospf6->vrf_id);
1801 if (oi == NULL || oi->area == NULL
1802 || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
1803 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
1804 RECV_HDR))
1805 zlog_debug("Message received on disabled interface");
1806 return OSPF6_READ_CONTINUE;
1807 }
1808 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)) {
1809 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
1810 RECV_HDR))
1811 zlog_debug("%s: Ignore message on passive interface %s",
1812 __func__, oi->interface->name);
1813 return OSPF6_READ_CONTINUE;
1814 }
1815
1816 /*
1817 * Drop packet destined to another VRF.
1818 * This happens when raw_l3mdev_accept is set to 1.
1819 */
1820 if (ospf6->vrf_id != oi->interface->vrf->vrf_id)
1821 return OSPF6_READ_CONTINUE;
1822
1823 oh = (struct ospf6_header *)recvbuf;
1824 ret = ospf6_auth_validate_pkt(oi, (uint32_t *)&len, oh, &at_len,
1825 &lls_len);
1826 if (ret == OSPF6_AUTH_VALIDATE_SUCCESS) {
1827 ret = ospf6_auth_check_digest(oh, oi, &src, lls_len);
1828 if (ret == OSPF6_AUTH_VALIDATE_FAILURE) {
1829 if (IS_OSPF6_DEBUG_AUTH_RX)
1830 zlog_err(
1831 "RECV[%s]: OSPF packet auth digest miss-match on %s",
1832 oi->interface->name,
1833 ospf6_message_type(oh->type));
1834 oi->at_data.rx_drop++;
1835 return OSPF6_READ_CONTINUE;
1836 }
1837 } else if (ret == OSPF6_AUTH_VALIDATE_FAILURE) {
1838 oi->at_data.rx_drop++;
1839 return OSPF6_READ_CONTINUE;
1840 }
1841
1842 if (ospf6_rxpacket_examin(oi, oh, len) != MSG_OK)
1843 return OSPF6_READ_CONTINUE;
1844
1845 /* Being here means, that no sizing/alignment issues were detected in
1846 the input packet. This renders the additional checks performed below
1847 and also in the type-specific dispatching functions a dead code,
1848 which can be dismissed in a cleanup-focused review round later. */
1849
1850 /* Log */
1851 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR)) {
1852 zlog_debug("%s received on %s", ospf6_message_type(oh->type),
1853 oi->interface->name);
1854 zlog_debug(" src: %pI6", &src);
1855 zlog_debug(" dst: %pI6", &dst);
1856
1857 switch (oh->type) {
1858 case OSPF6_MESSAGE_TYPE_HELLO:
1859 ospf6_hello_print(oh, OSPF6_ACTION_RECV);
1860 break;
1861 case OSPF6_MESSAGE_TYPE_DBDESC:
1862 ospf6_dbdesc_print(oh, OSPF6_ACTION_RECV);
1863 break;
1864 case OSPF6_MESSAGE_TYPE_LSREQ:
1865 ospf6_lsreq_print(oh, OSPF6_ACTION_RECV);
1866 break;
1867 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1868 ospf6_lsupdate_print(oh, OSPF6_ACTION_RECV);
1869 break;
1870 case OSPF6_MESSAGE_TYPE_LSACK:
1871 ospf6_lsack_print(oh, OSPF6_ACTION_RECV);
1872 break;
1873 default:
1874 assert(0);
1875 }
1876
1877 if ((at_len != 0) && IS_OSPF6_DEBUG_AUTH_RX)
1878 ospf6_auth_hdr_dump_recv(oh, (len + at_len + lls_len),
1879 lls_len);
1880 }
1881
1882 switch (oh->type) {
1883 case OSPF6_MESSAGE_TYPE_HELLO:
1884 ospf6_hello_recv(&src, &dst, oi, oh);
1885 break;
1886
1887 case OSPF6_MESSAGE_TYPE_DBDESC:
1888 ospf6_dbdesc_recv(&src, &dst, oi, oh);
1889 break;
1890
1891 case OSPF6_MESSAGE_TYPE_LSREQ:
1892 ospf6_lsreq_recv(&src, &dst, oi, oh);
1893 break;
1894
1895 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1896 ospf6_lsupdate_recv(&src, &dst, oi, oh);
1897 break;
1898
1899 case OSPF6_MESSAGE_TYPE_LSACK:
1900 ospf6_lsack_recv(&src, &dst, oi, oh);
1901 break;
1902
1903 default:
1904 assert(0);
1905 }
1906
1907 return OSPF6_READ_CONTINUE;
1908 }
1909
1910 void ospf6_receive(struct event *thread)
1911 {
1912 int sockfd;
1913 struct ospf6 *ospf6;
1914 int count = 0;
1915
1916 /* add next read thread */
1917 ospf6 = EVENT_ARG(thread);
1918 sockfd = EVENT_FD(thread);
1919
1920 event_add_read(master, ospf6_receive, ospf6, ospf6->fd,
1921 &ospf6->t_ospf6_receive);
1922
1923 while (count < ospf6->write_oi_count) {
1924 count++;
1925 switch (ospf6_read_helper(sockfd, ospf6)) {
1926 case OSPF6_READ_ERROR:
1927 return;
1928 case OSPF6_READ_CONTINUE:
1929 break;
1930 }
1931 }
1932 }
1933
1934 static void ospf6_fill_hdr_checksum(struct ospf6_interface *oi,
1935 struct ospf6_packet *op)
1936 {
1937 struct ipv6_ph ph = {};
1938 struct ospf6_header *oh;
1939 void *offset = NULL;
1940
1941 if (oi->at_data.flags != 0)
1942 return;
1943
1944 memcpy(&ph.src, oi->linklocal_addr, sizeof(struct in6_addr));
1945 memcpy(&ph.dst, &op->dst, sizeof(struct in6_addr));
1946 ph.ulpl = htonl(op->length);
1947 ph.next_hdr = IPPROTO_OSPFIGP;
1948
1949 /* Suppress static analysis warnings about accessing icmp6 oob */
1950 oh = (struct ospf6_header *)STREAM_DATA(op->s);
1951 offset = oh;
1952 oh->checksum = in_cksum_with_ph6(&ph, offset, op->length);
1953 }
1954
1955 static void ospf6_make_header(uint8_t type, struct ospf6_interface *oi,
1956 struct stream *s)
1957 {
1958 struct ospf6_header *oh;
1959
1960 oh = (struct ospf6_header *)STREAM_DATA(s);
1961
1962 oh->version = (uint8_t)OSPFV3_VERSION;
1963 oh->type = type;
1964 oh->length = 0;
1965
1966 oh->router_id = oi->area->ospf6->router_id;
1967 oh->area_id = oi->area->area_id;
1968 oh->checksum = 0;
1969 oh->instance_id = oi->instance_id;
1970 oh->reserved = 0;
1971
1972 stream_forward_endp(s, OSPF6_HEADER_SIZE);
1973 }
1974
1975 static void ospf6_fill_header(struct ospf6_interface *oi, struct stream *s,
1976 uint16_t length)
1977 {
1978 struct ospf6_header *oh;
1979
1980 oh = (struct ospf6_header *)STREAM_DATA(s);
1981
1982 oh->length = htons(length);
1983 }
1984
1985 static void ospf6_fill_lsupdate_header(struct stream *s, uint32_t lsa_num)
1986 {
1987 struct ospf6_header *oh;
1988 struct ospf6_lsupdate *lsu;
1989
1990 oh = (struct ospf6_header *)STREAM_DATA(s);
1991
1992 lsu = (struct ospf6_lsupdate *)((caddr_t)oh
1993 + sizeof(struct ospf6_header));
1994 lsu->lsa_number = htonl(lsa_num);
1995 }
1996
1997 static void ospf6_auth_trailer_copy_keychain_key(struct ospf6_interface *oi)
1998 {
1999 char *keychain_name = NULL;
2000 struct keychain *keychain = NULL;
2001 struct key *key = NULL;
2002
2003 keychain_name = oi->at_data.keychain;
2004 keychain = keychain_lookup(keychain_name);
2005 if (keychain) {
2006 key = key_lookup_for_send(keychain);
2007 if (key && key->string &&
2008 key->hash_algo != KEYCHAIN_ALGO_NULL) {
2009 /* storing the values so that further
2010 * lookup can be avoided. after
2011 * processing the digest need to reset
2012 * these values
2013 */
2014 oi->at_data.hash_algo = key->hash_algo;
2015 if (oi->at_data.auth_key)
2016 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY,
2017 oi->at_data.auth_key);
2018 oi->at_data.auth_key = XSTRDUP(
2019 MTYPE_OSPF6_AUTH_MANUAL_KEY, key->string);
2020 oi->at_data.key_id = key->index;
2021 SET_FLAG(oi->at_data.flags,
2022 OSPF6_AUTH_TRAILER_KEYCHAIN_VALID);
2023 }
2024 }
2025 }
2026
2027 static uint16_t ospf6_packet_max(struct ospf6_interface *oi)
2028 {
2029 uint16_t at_len = 0;
2030
2031 assert(oi->ifmtu > sizeof(struct ip6_hdr));
2032
2033 if (oi->at_data.flags != 0) {
2034 if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN))
2035 ospf6_auth_trailer_copy_keychain_key(oi);
2036
2037 at_len += OSPF6_AUTH_HDR_MIN_SIZE;
2038 at_len += keychain_get_hash_len(oi->at_data.hash_algo);
2039 return oi->ifmtu - (sizeof(struct ip6_hdr)) - at_len;
2040 }
2041
2042 return oi->ifmtu - (sizeof(struct ip6_hdr));
2043 }
2044
2045 static uint16_t ospf6_make_hello(struct ospf6_interface *oi, struct stream *s)
2046 {
2047 struct listnode *node, *nnode;
2048 struct ospf6_neighbor *on;
2049 uint16_t length = OSPF6_HELLO_MIN_SIZE;
2050 uint8_t options1 = oi->area->options[1];
2051
2052 if (oi->at_data.flags != 0)
2053 options1 |= OSPF6_OPT_AT;
2054
2055 stream_putl(s, oi->interface->ifindex);
2056 stream_putc(s, oi->priority);
2057 stream_putc(s, oi->area->options[0]);
2058 stream_putc(s, options1);
2059 stream_putc(s, oi->area->options[2]);
2060 stream_putw(s, oi->hello_interval);
2061 stream_putw(s, oi->dead_interval);
2062 stream_put_ipv4(s, oi->drouter);
2063 stream_put_ipv4(s, oi->bdrouter);
2064
2065 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
2066 if (on->state < OSPF6_NEIGHBOR_INIT)
2067 continue;
2068
2069 if ((length + sizeof(uint32_t) + OSPF6_HEADER_SIZE)
2070 > ospf6_packet_max(oi)) {
2071 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO,
2072 SEND))
2073 zlog_debug(
2074 "sending Hello message: exceeds I/F MTU");
2075 break;
2076 }
2077
2078 stream_put_ipv4(s, on->router_id);
2079 length += sizeof(uint32_t);
2080 }
2081
2082 return length;
2083 }
2084
2085 static void ospf6_write(struct event *thread)
2086 {
2087 struct ospf6 *ospf6 = EVENT_ARG(thread);
2088 struct ospf6_interface *oi;
2089 struct ospf6_header *oh;
2090 struct ospf6_packet *op;
2091 struct listnode *node;
2092 struct iovec iovector[2];
2093 int pkt_count = 0;
2094 int len;
2095 int64_t latency = 0;
2096 struct timeval timestamp;
2097 uint16_t at_len = 0;
2098
2099 if (ospf6->fd < 0) {
2100 zlog_warn("ospf6_write failed to send, fd %d", ospf6->fd);
2101 return;
2102 }
2103
2104 node = listhead(ospf6->oi_write_q);
2105 assert(node);
2106 oi = listgetdata(node);
2107
2108 while ((pkt_count < ospf6->write_oi_count) && oi) {
2109 op = ospf6_fifo_head(oi->obuf);
2110 assert(op);
2111 assert(op->length >= OSPF6_HEADER_SIZE);
2112
2113 iovector[0].iov_base = (caddr_t)stream_pnt(op->s);
2114 iovector[0].iov_len = op->length;
2115 iovector[1].iov_base = NULL;
2116 iovector[1].iov_len = 0;
2117
2118 oh = (struct ospf6_header *)STREAM_DATA(op->s);
2119
2120 if (oi->at_data.flags != 0) {
2121 at_len = ospf6_auth_len_get(oi);
2122 if (at_len) {
2123 iovector[0].iov_len =
2124 ntohs(oh->length) + at_len;
2125 ospf6_auth_digest_send(oi->linklocal_addr, oi,
2126 oh, at_len,
2127 iovector[0].iov_len);
2128 } else {
2129 iovector[0].iov_len = ntohs(oh->length);
2130 }
2131 } else {
2132 iovector[0].iov_len = ntohs(oh->length);
2133 }
2134
2135 len = ospf6_sendmsg(oi->linklocal_addr, &op->dst,
2136 oi->interface->ifindex, iovector,
2137 ospf6->fd);
2138
2139 if (len != (op->length + (int)at_len))
2140 flog_err(EC_LIB_DEVELOPMENT,
2141 "Could not send entire message");
2142
2143 if (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND_HDR)) {
2144 zlog_debug("%s send on %s",
2145 ospf6_message_type(oh->type),
2146 oi->interface->name);
2147 zlog_debug(" src: %pI6", oi->linklocal_addr);
2148 zlog_debug(" dst: %pI6", &op->dst);
2149 switch (oh->type) {
2150 case OSPF6_MESSAGE_TYPE_HELLO:
2151 ospf6_hello_print(oh, OSPF6_ACTION_SEND);
2152 break;
2153 case OSPF6_MESSAGE_TYPE_DBDESC:
2154 ospf6_dbdesc_print(oh, OSPF6_ACTION_SEND);
2155 break;
2156 case OSPF6_MESSAGE_TYPE_LSREQ:
2157 ospf6_lsreq_print(oh, OSPF6_ACTION_SEND);
2158 break;
2159 case OSPF6_MESSAGE_TYPE_LSUPDATE:
2160 ospf6_lsupdate_print(oh, OSPF6_ACTION_SEND);
2161 break;
2162 case OSPF6_MESSAGE_TYPE_LSACK:
2163 ospf6_lsack_print(oh, OSPF6_ACTION_SEND);
2164 break;
2165 default:
2166 zlog_debug("Unknown message");
2167 assert(0);
2168 break;
2169 }
2170 }
2171 switch (oh->type) {
2172 case OSPF6_MESSAGE_TYPE_HELLO:
2173 monotime(&timestamp);
2174 if (oi->hello_out)
2175 latency = monotime_since(&oi->last_hello, NULL)
2176 - ((int64_t)oi->hello_interval
2177 * 1000000);
2178
2179 /* log if latency exceeds the hello period */
2180 if (latency > ((int64_t)oi->hello_interval * 1000000))
2181 zlog_warn("%s hello TX high latency %" PRId64
2182 "us.",
2183 __func__, latency);
2184 oi->last_hello = timestamp;
2185 oi->hello_out++;
2186 break;
2187 case OSPF6_MESSAGE_TYPE_DBDESC:
2188 oi->db_desc_out++;
2189 break;
2190 case OSPF6_MESSAGE_TYPE_LSREQ:
2191 oi->ls_req_out++;
2192 break;
2193 case OSPF6_MESSAGE_TYPE_LSUPDATE:
2194 oi->ls_upd_out++;
2195 break;
2196 case OSPF6_MESSAGE_TYPE_LSACK:
2197 oi->ls_ack_out++;
2198 break;
2199 default:
2200 zlog_debug("Unknown message");
2201 assert(0);
2202 break;
2203 }
2204
2205 if ((oi->at_data.flags != 0) &&
2206 (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND_HDR)) &&
2207 (IS_OSPF6_DEBUG_AUTH_TX))
2208 ospf6_auth_hdr_dump_send(oh, iovector[0].iov_len);
2209
2210 /* initialize at_len to 0 for next packet */
2211 at_len = 0;
2212
2213 /* Now delete packet from queue. */
2214 ospf6_packet_delete(oi);
2215
2216 /* Move this interface to the tail of write_q to
2217 serve everyone in a round robin fashion */
2218 list_delete_node(ospf6->oi_write_q, node);
2219 if (ospf6_fifo_head(oi->obuf) == NULL) {
2220 oi->on_write_q = 0;
2221 oi = NULL;
2222 } else {
2223 listnode_add(ospf6->oi_write_q, oi);
2224 }
2225
2226 /* Setup to service from the head of the queue again */
2227 if (!list_isempty(ospf6->oi_write_q)) {
2228 node = listhead(ospf6->oi_write_q);
2229 oi = listgetdata(node);
2230 }
2231 }
2232
2233 /* If packets still remain in queue, call write thread. */
2234 if (!list_isempty(ospf6->oi_write_q))
2235 event_add_write(master, ospf6_write, ospf6, ospf6->fd,
2236 &ospf6->t_write);
2237 }
2238
2239 void ospf6_hello_send(struct event *thread)
2240 {
2241 struct ospf6_interface *oi;
2242 struct ospf6_packet *op;
2243 uint16_t length = OSPF6_HEADER_SIZE;
2244
2245 oi = (struct ospf6_interface *)EVENT_ARG(thread);
2246
2247 if (oi->state <= OSPF6_INTERFACE_DOWN) {
2248 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, SEND_HDR))
2249 zlog_debug("Unable to send Hello on down interface %s",
2250 oi->interface->name);
2251 return;
2252 }
2253
2254 op = ospf6_packet_new(oi->ifmtu);
2255
2256 ospf6_make_header(OSPF6_MESSAGE_TYPE_HELLO, oi, op->s);
2257
2258 /* Prepare OSPF Hello body */
2259 length += ospf6_make_hello(oi, op->s);
2260 if (length == OSPF6_HEADER_SIZE) {
2261 /* Hello overshooting MTU */
2262 ospf6_packet_free(op);
2263 return;
2264 }
2265
2266 /* Fill OSPF header. */
2267 ospf6_fill_header(oi, op->s, length);
2268
2269 /* Set packet length. */
2270 op->length = length;
2271
2272 op->dst = allspfrouters6;
2273
2274 ospf6_fill_hdr_checksum(oi, op);
2275
2276 /* Add packet to the top of the interface output queue, so that they
2277 * can't get delayed by things like long queues of LS Update packets
2278 */
2279 ospf6_packet_add_top(oi, op);
2280
2281 /* set next thread */
2282 event_add_timer(master, ospf6_hello_send, oi, oi->hello_interval,
2283 &oi->thread_send_hello);
2284
2285 OSPF6_MESSAGE_WRITE_ON(oi);
2286 }
2287
2288 static uint16_t ospf6_make_dbdesc(struct ospf6_neighbor *on, struct stream *s)
2289 {
2290 uint16_t length = OSPF6_DB_DESC_MIN_SIZE;
2291 struct ospf6_lsa *lsa, *lsanext;
2292 uint8_t options1 = on->ospf6_if->area->options[1];
2293
2294 if (on->ospf6_if->at_data.flags != 0)
2295 options1 |= OSPF6_OPT_AT;
2296
2297 /* if this is initial one, initialize sequence number for DbDesc */
2298 if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)
2299 && (on->dbdesc_seqnum == 0)) {
2300 on->dbdesc_seqnum = frr_sequence32_next();
2301 }
2302
2303 /* reserved */
2304 stream_putc(s, 0); /* reserved 1 */
2305 stream_putc(s, on->ospf6_if->area->options[0]);
2306 stream_putc(s, options1);
2307 stream_putc(s, on->ospf6_if->area->options[2]);
2308 stream_putw(s, on->ospf6_if->ifmtu);
2309 stream_putc(s, 0); /* reserved 2 */
2310 stream_putc(s, on->dbdesc_bits);
2311 stream_putl(s, on->dbdesc_seqnum);
2312
2313 /* if this is not initial one, set LSA headers in dbdesc */
2314 if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)) {
2315 for (ALL_LSDB(on->dbdesc_list, lsa, lsanext)) {
2316 ospf6_lsa_age_update_to_send(lsa,
2317 on->ospf6_if->transdelay);
2318
2319 /* MTU check */
2320 if ((length + sizeof(struct ospf6_lsa_header)
2321 + OSPF6_HEADER_SIZE)
2322 > ospf6_packet_max(on->ospf6_if)) {
2323 ospf6_lsa_unlock(lsa);
2324 if (lsanext)
2325 ospf6_lsa_unlock(lsanext);
2326 break;
2327 }
2328 stream_put(s, lsa->header,
2329 sizeof(struct ospf6_lsa_header));
2330 length += sizeof(struct ospf6_lsa_header);
2331 }
2332 }
2333 return length;
2334 }
2335
2336 void ospf6_dbdesc_send(struct event *thread)
2337 {
2338 struct ospf6_neighbor *on;
2339 uint16_t length = OSPF6_HEADER_SIZE;
2340 struct ospf6_packet *op;
2341
2342 on = (struct ospf6_neighbor *)EVENT_ARG(thread);
2343
2344 if (on->state < OSPF6_NEIGHBOR_EXSTART) {
2345 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_DBDESC, SEND))
2346 zlog_debug(
2347 "Quit to send DbDesc to neighbor %s state %s",
2348 on->name, ospf6_neighbor_state_str[on->state]);
2349 return;
2350 }
2351
2352 /* set next thread if master */
2353 if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
2354 event_add_timer(master, ospf6_dbdesc_send, on,
2355 on->ospf6_if->rxmt_interval,
2356 &on->thread_send_dbdesc);
2357
2358 op = ospf6_packet_new(on->ospf6_if->ifmtu);
2359 ospf6_make_header(OSPF6_MESSAGE_TYPE_DBDESC, on->ospf6_if, op->s);
2360
2361 length += ospf6_make_dbdesc(on, op->s);
2362 ospf6_fill_header(on->ospf6_if, op->s, length);
2363
2364 /* Set packet length. */
2365 op->length = length;
2366
2367 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
2368 op->dst = allspfrouters6;
2369 else
2370 op->dst = on->linklocal_addr;
2371
2372 ospf6_fill_hdr_checksum(on->ospf6_if, op);
2373
2374 ospf6_packet_add(on->ospf6_if, op);
2375
2376 OSPF6_MESSAGE_WRITE_ON(on->ospf6_if);
2377 }
2378
2379 void ospf6_dbdesc_send_newone(struct event *thread)
2380 {
2381 struct ospf6_neighbor *on;
2382 struct ospf6_lsa *lsa, *lsanext;
2383 unsigned int size = 0;
2384
2385 on = (struct ospf6_neighbor *)EVENT_ARG(thread);
2386 ospf6_lsdb_remove_all(on->dbdesc_list);
2387
2388 /* move LSAs from summary_list to dbdesc_list (within neighbor
2389 structure)
2390 so that ospf6_send_dbdesc () can send those LSAs */
2391 size = sizeof(struct ospf6_lsa_header) + sizeof(struct ospf6_dbdesc);
2392 for (ALL_LSDB(on->summary_list, lsa, lsanext)) {
2393 /* if stub area then don't advertise AS-External LSAs */
2394 if ((IS_AREA_STUB(on->ospf6_if->area)
2395 || IS_AREA_NSSA(on->ospf6_if->area))
2396 && ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL) {
2397 ospf6_lsdb_remove(lsa, on->summary_list);
2398 continue;
2399 }
2400
2401 if (size + sizeof(struct ospf6_lsa_header)
2402 > ospf6_packet_max(on->ospf6_if)) {
2403 ospf6_lsa_unlock(lsa);
2404 if (lsanext)
2405 ospf6_lsa_unlock(lsanext);
2406 break;
2407 }
2408
2409 ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->dbdesc_list);
2410 ospf6_lsdb_remove(lsa, on->summary_list);
2411 size += sizeof(struct ospf6_lsa_header);
2412 }
2413
2414 if (on->summary_list->count == 0)
2415 UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
2416
2417 /* If slave, More bit check must be done here */
2418 if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
2419 !CHECK_FLAG(on->dbdesc_last.bits, OSPF6_DBDESC_MBIT)
2420 && !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT))
2421 event_add_event(master, exchange_done, on, 0,
2422 &on->thread_exchange_done);
2423
2424 event_execute(master, ospf6_dbdesc_send, on, 0);
2425 }
2426
2427 static uint16_t ospf6_make_lsreq(struct ospf6_neighbor *on, struct stream *s)
2428 {
2429 uint16_t length = 0;
2430 struct ospf6_lsa *lsa, *lsanext, *last_req = NULL;
2431
2432 for (ALL_LSDB(on->request_list, lsa, lsanext)) {
2433 if ((length + OSPF6_HEADER_SIZE)
2434 > ospf6_packet_max(on->ospf6_if)) {
2435 ospf6_lsa_unlock(lsa);
2436 if (lsanext)
2437 ospf6_lsa_unlock(lsanext);
2438 break;
2439 }
2440 stream_putw(s, 0); /* reserved */
2441 stream_putw(s, ntohs(lsa->header->type));
2442 stream_putl(s, ntohl(lsa->header->id));
2443 stream_putl(s, ntohl(lsa->header->adv_router));
2444 length += sizeof(struct ospf6_lsreq_entry);
2445 last_req = lsa;
2446 }
2447
2448 if (last_req != NULL) {
2449 if (on->last_ls_req != NULL)
2450 on->last_ls_req = ospf6_lsa_unlock(on->last_ls_req);
2451
2452 ospf6_lsa_lock(last_req);
2453 on->last_ls_req = last_req;
2454 }
2455
2456 return length;
2457 }
2458
2459 static uint16_t ospf6_make_lsack_neighbor(struct ospf6_neighbor *on,
2460 struct ospf6_packet **op)
2461 {
2462 uint16_t length = 0;
2463 struct ospf6_lsa *lsa, *lsanext;
2464 int lsa_cnt = 0;
2465
2466 for (ALL_LSDB(on->lsack_list, lsa, lsanext)) {
2467 if ((length + sizeof(struct ospf6_lsa_header)
2468 + OSPF6_HEADER_SIZE)
2469 > ospf6_packet_max(on->ospf6_if)) {
2470 /* if we run out of packet size/space here,
2471 better to try again soon. */
2472 if (lsa_cnt) {
2473 ospf6_fill_header(on->ospf6_if, (*op)->s,
2474 length + OSPF6_HEADER_SIZE);
2475
2476 (*op)->length = length + OSPF6_HEADER_SIZE;
2477 (*op)->dst = on->linklocal_addr;
2478 ospf6_fill_hdr_checksum(on->ospf6_if, *op);
2479 ospf6_packet_add(on->ospf6_if, *op);
2480 OSPF6_MESSAGE_WRITE_ON(on->ospf6_if);
2481 /* new packet */
2482 *op = ospf6_packet_new(on->ospf6_if->ifmtu);
2483 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSACK,
2484 on->ospf6_if, (*op)->s);
2485 length = 0;
2486 lsa_cnt = 0;
2487 }
2488 }
2489 ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay);
2490 stream_put((*op)->s, lsa->header,
2491 sizeof(struct ospf6_lsa_header));
2492 length += sizeof(struct ospf6_lsa_header);
2493
2494 assert(lsa->lock == 2);
2495 ospf6_lsdb_remove(lsa, on->lsack_list);
2496 lsa_cnt++;
2497 }
2498 return length;
2499 }
2500
2501 void ospf6_lsreq_send(struct event *thread)
2502 {
2503 struct ospf6_neighbor *on;
2504 struct ospf6_packet *op;
2505 uint16_t length = OSPF6_HEADER_SIZE;
2506
2507 on = (struct ospf6_neighbor *)EVENT_ARG(thread);
2508
2509 /* LSReq will be sent only in ExStart or Loading */
2510 if (on->state != OSPF6_NEIGHBOR_EXCHANGE
2511 && on->state != OSPF6_NEIGHBOR_LOADING) {
2512 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSREQ, SEND_HDR))
2513 zlog_debug("Quit to send LSReq to neighbor %s state %s",
2514 on->name,
2515 ospf6_neighbor_state_str[on->state]);
2516 return;
2517 }
2518
2519 /* schedule loading_done if request list is empty */
2520 if (on->request_list->count == 0) {
2521 event_add_event(master, loading_done, on, 0, NULL);
2522 return;
2523 }
2524
2525 op = ospf6_packet_new(on->ospf6_if->ifmtu);
2526 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSREQ, on->ospf6_if, op->s);
2527
2528 length += ospf6_make_lsreq(on, op->s);
2529
2530 if (length == OSPF6_HEADER_SIZE) {
2531 /* Hello overshooting MTU */
2532 ospf6_packet_free(op);
2533 return;
2534 }
2535
2536 /* Fill OSPF header. */
2537 ospf6_fill_header(on->ospf6_if, op->s, length);
2538
2539 /* Set packet length */
2540 op->length = length;
2541
2542 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
2543 op->dst = allspfrouters6;
2544 else
2545 op->dst = on->linklocal_addr;
2546
2547 ospf6_fill_hdr_checksum(on->ospf6_if, op);
2548 ospf6_packet_add(on->ospf6_if, op);
2549
2550 OSPF6_MESSAGE_WRITE_ON(on->ospf6_if);
2551
2552 /* set next thread */
2553 if (on->request_list->count != 0) {
2554 event_add_timer(master, ospf6_lsreq_send, on,
2555 on->ospf6_if->rxmt_interval,
2556 &on->thread_send_lsreq);
2557 }
2558 }
2559
2560 static void ospf6_send_lsupdate(struct ospf6_neighbor *on,
2561 struct ospf6_interface *oi,
2562 struct ospf6_packet *op)
2563 {
2564
2565 if (on) {
2566
2567 if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
2568 || (on->ospf6_if->state == OSPF6_INTERFACE_DR)
2569 || (on->ospf6_if->state == OSPF6_INTERFACE_BDR))
2570 op->dst = allspfrouters6;
2571 else
2572 op->dst = on->linklocal_addr;
2573 oi = on->ospf6_if;
2574 } else if (oi) {
2575 if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT)
2576 || (oi->state == OSPF6_INTERFACE_DR)
2577 || (oi->state == OSPF6_INTERFACE_BDR))
2578 op->dst = allspfrouters6;
2579 else
2580 op->dst = alldrouters6;
2581 }
2582 if (oi) {
2583 ospf6_fill_hdr_checksum(oi, op);
2584 ospf6_packet_add(oi, op);
2585 /* If ospf instance is being deleted, send the packet
2586 * immediately
2587 */
2588 if ((oi->area == NULL) || (oi->area->ospf6 == NULL))
2589 return;
2590 if (oi->area->ospf6->inst_shutdown) {
2591 if (oi->on_write_q == 0) {
2592 listnode_add(oi->area->ospf6->oi_write_q, oi);
2593 oi->on_write_q = 1;
2594 }
2595 event_execute(master, ospf6_write, oi->area->ospf6, 0);
2596 } else
2597 OSPF6_MESSAGE_WRITE_ON(oi);
2598 }
2599 }
2600
2601 static uint16_t ospf6_make_lsupdate_list(struct ospf6_neighbor *on,
2602 struct ospf6_packet **op, int *lsa_cnt)
2603 {
2604 uint16_t length = OSPF6_LS_UPD_MIN_SIZE;
2605 struct ospf6_lsa *lsa, *lsanext;
2606
2607 /* skip over fixed header */
2608 stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE);
2609
2610 for (ALL_LSDB(on->lsupdate_list, lsa, lsanext)) {
2611 if ((length + OSPF6_LSA_SIZE(lsa->header) + OSPF6_HEADER_SIZE) >
2612 ospf6_packet_max(on->ospf6_if)) {
2613 ospf6_fill_header(on->ospf6_if, (*op)->s,
2614 length + OSPF6_HEADER_SIZE);
2615 (*op)->length = length + OSPF6_HEADER_SIZE;
2616 ospf6_fill_lsupdate_header((*op)->s, *lsa_cnt);
2617 ospf6_send_lsupdate(on, NULL, *op);
2618
2619 /* refresh packet */
2620 *op = ospf6_packet_new(on->ospf6_if->ifmtu);
2621 length = OSPF6_LS_UPD_MIN_SIZE;
2622 *lsa_cnt = 0;
2623 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE,
2624 on->ospf6_if, (*op)->s);
2625 stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE);
2626 }
2627 ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay);
2628 stream_put((*op)->s, lsa->header, OSPF6_LSA_SIZE(lsa->header));
2629 (*lsa_cnt)++;
2630 length += OSPF6_LSA_SIZE(lsa->header);
2631 assert(lsa->lock == 2);
2632 ospf6_lsdb_remove(lsa, on->lsupdate_list);
2633 }
2634 return length;
2635 }
2636
2637 static uint16_t ospf6_make_ls_retrans_list(struct ospf6_neighbor *on,
2638 struct ospf6_packet **op,
2639 int *lsa_cnt)
2640 {
2641 uint16_t length = OSPF6_LS_UPD_MIN_SIZE;
2642 struct ospf6_lsa *lsa, *lsanext;
2643
2644 /* skip over fixed header */
2645 stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE);
2646
2647 for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
2648 if ((length + OSPF6_LSA_SIZE(lsa->header) + OSPF6_HEADER_SIZE) >
2649 ospf6_packet_max(on->ospf6_if)) {
2650 ospf6_fill_header(on->ospf6_if, (*op)->s,
2651 length + OSPF6_HEADER_SIZE);
2652 (*op)->length = length + OSPF6_HEADER_SIZE;
2653 ospf6_fill_lsupdate_header((*op)->s, *lsa_cnt);
2654 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
2655 (*op)->dst = allspfrouters6;
2656 else
2657 (*op)->dst = on->linklocal_addr;
2658
2659 ospf6_fill_hdr_checksum(on->ospf6_if, *op);
2660 ospf6_packet_add(on->ospf6_if, *op);
2661 OSPF6_MESSAGE_WRITE_ON(on->ospf6_if);
2662
2663 /* refresh packet */
2664 *op = ospf6_packet_new(on->ospf6_if->ifmtu);
2665 length = OSPF6_LS_UPD_MIN_SIZE;
2666 *lsa_cnt = 0;
2667 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE,
2668 on->ospf6_if, (*op)->s);
2669 stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE);
2670 }
2671 ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay);
2672 stream_put((*op)->s, lsa->header, OSPF6_LSA_SIZE(lsa->header));
2673 (*lsa_cnt)++;
2674 length += OSPF6_LSA_SIZE(lsa->header);
2675 }
2676 return length;
2677 }
2678
2679 void ospf6_lsupdate_send_neighbor(struct event *thread)
2680 {
2681 struct ospf6_neighbor *on;
2682 struct ospf6_packet *op;
2683 uint16_t length = OSPF6_HEADER_SIZE;
2684 int lsa_cnt = 0;
2685
2686 on = (struct ospf6_neighbor *)EVENT_ARG(thread);
2687
2688 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND_HDR))
2689 zlog_debug("LSUpdate to neighbor %s", on->name);
2690
2691 if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
2692 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE,
2693 SEND_HDR))
2694 zlog_debug("Quit to send (neighbor state %s)",
2695 ospf6_neighbor_state_str[on->state]);
2696 return;
2697 }
2698
2699 /* first do lsupdate_list */
2700 op = ospf6_packet_new(on->ospf6_if->ifmtu);
2701 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE, on->ospf6_if, op->s);
2702 length += ospf6_make_lsupdate_list(on, &op, &lsa_cnt);
2703 if (lsa_cnt) {
2704 /* Fill OSPF header. */
2705 ospf6_fill_header(on->ospf6_if, op->s, length);
2706 ospf6_fill_lsupdate_header(op->s, lsa_cnt);
2707 op->length = length;
2708 ospf6_send_lsupdate(on, NULL, op);
2709
2710 /* prepare new packet */
2711 op = ospf6_packet_new(on->ospf6_if->ifmtu);
2712 length = OSPF6_HEADER_SIZE;
2713 lsa_cnt = 0;
2714 } else {
2715 stream_reset(op->s);
2716 length = OSPF6_HEADER_SIZE;
2717 }
2718
2719 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE, on->ospf6_if, op->s);
2720 /* now do retransmit list */
2721 length += ospf6_make_ls_retrans_list(on, &op, &lsa_cnt);
2722 if (lsa_cnt) {
2723 ospf6_fill_header(on->ospf6_if, op->s, length);
2724 ospf6_fill_lsupdate_header(op->s, lsa_cnt);
2725 op->length = length;
2726 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
2727 op->dst = allspfrouters6;
2728 else
2729 op->dst = on->linklocal_addr;
2730 ospf6_fill_hdr_checksum(on->ospf6_if, op);
2731 ospf6_packet_add(on->ospf6_if, op);
2732 OSPF6_MESSAGE_WRITE_ON(on->ospf6_if);
2733 } else
2734 ospf6_packet_free(op);
2735
2736 if (on->lsupdate_list->count != 0) {
2737 event_add_event(master, ospf6_lsupdate_send_neighbor, on, 0,
2738 &on->thread_send_lsupdate);
2739 } else if (on->retrans_list->count != 0) {
2740 event_add_timer(master, ospf6_lsupdate_send_neighbor, on,
2741 on->ospf6_if->rxmt_interval,
2742 &on->thread_send_lsupdate);
2743 }
2744 }
2745
2746 int ospf6_lsupdate_send_neighbor_now(struct ospf6_neighbor *on,
2747 struct ospf6_lsa *lsa)
2748 {
2749 struct ospf6_packet *op;
2750 uint16_t length = OSPF6_HEADER_SIZE;
2751
2752 op = ospf6_packet_new(on->ospf6_if->ifmtu);
2753 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE, on->ospf6_if, op->s);
2754
2755 /* skip over fixed header */
2756 stream_forward_endp(op->s, OSPF6_LS_UPD_MIN_SIZE);
2757 ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay);
2758 stream_put(op->s, lsa->header, OSPF6_LSA_SIZE(lsa->header));
2759 length = OSPF6_HEADER_SIZE + OSPF6_LS_UPD_MIN_SIZE
2760 + OSPF6_LSA_SIZE(lsa->header);
2761 ospf6_fill_header(on->ospf6_if, op->s, length);
2762 ospf6_fill_lsupdate_header(op->s, 1);
2763 op->length = length;
2764
2765 if (IS_OSPF6_DEBUG_FLOODING
2766 || IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND_HDR))
2767 zlog_debug("%s: Send lsupdate with lsa %s (age %u)", __func__,
2768 lsa->name, ntohs(lsa->header->age));
2769
2770 ospf6_send_lsupdate(on, NULL, op);
2771
2772 return 0;
2773 }
2774
2775 static uint16_t ospf6_make_lsupdate_interface(struct ospf6_interface *oi,
2776 struct ospf6_packet **op,
2777 int *lsa_cnt)
2778 {
2779 uint16_t length = OSPF6_LS_UPD_MIN_SIZE;
2780 struct ospf6_lsa *lsa, *lsanext;
2781
2782 /* skip over fixed header */
2783 stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE);
2784
2785 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext)) {
2786 if (length + OSPF6_LSA_SIZE(lsa->header) + OSPF6_HEADER_SIZE >
2787 ospf6_packet_max(oi)) {
2788 ospf6_fill_header(oi, (*op)->s,
2789 length + OSPF6_HEADER_SIZE);
2790 (*op)->length = length + OSPF6_HEADER_SIZE;
2791 ospf6_fill_lsupdate_header((*op)->s, *lsa_cnt);
2792 ospf6_send_lsupdate(NULL, oi, *op);
2793
2794 /* refresh packet */
2795 *op = ospf6_packet_new(oi->ifmtu);
2796 length = OSPF6_LS_UPD_MIN_SIZE;
2797 *lsa_cnt = 0;
2798 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE, oi,
2799 (*op)->s);
2800 stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE);
2801 }
2802
2803 ospf6_lsa_age_update_to_send(lsa, oi->transdelay);
2804 stream_put((*op)->s, lsa->header, OSPF6_LSA_SIZE(lsa->header));
2805 (*lsa_cnt)++;
2806 length += OSPF6_LSA_SIZE(lsa->header);
2807
2808 assert(lsa->lock == 2);
2809 ospf6_lsdb_remove(lsa, oi->lsupdate_list);
2810 }
2811 return length;
2812 }
2813
2814 void ospf6_lsupdate_send_interface(struct event *thread)
2815 {
2816 struct ospf6_interface *oi;
2817 struct ospf6_packet *op;
2818 uint16_t length = OSPF6_HEADER_SIZE;
2819 int lsa_cnt = 0;
2820
2821 oi = (struct ospf6_interface *)EVENT_ARG(thread);
2822
2823 if (oi->state <= OSPF6_INTERFACE_WAITING) {
2824 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE,
2825 SEND_HDR))
2826 zlog_debug(
2827 "Quit to send LSUpdate to interface %s state %s",
2828 oi->interface->name,
2829 ospf6_interface_state_str[oi->state]);
2830 return;
2831 }
2832
2833 /* if we have nothing to send, return */
2834 if (oi->lsupdate_list->count == 0)
2835 return;
2836
2837 op = ospf6_packet_new(oi->ifmtu);
2838 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE, oi, op->s);
2839 length += ospf6_make_lsupdate_interface(oi, &op, &lsa_cnt);
2840 if (lsa_cnt) {
2841 /* Fill OSPF header. */
2842 ospf6_fill_header(oi, op->s, length);
2843 ospf6_fill_lsupdate_header(op->s, lsa_cnt);
2844 op->length = length;
2845 ospf6_send_lsupdate(NULL, oi, op);
2846 } else
2847 ospf6_packet_free(op);
2848
2849 if (oi->lsupdate_list->count > 0) {
2850 event_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
2851 &oi->thread_send_lsupdate);
2852 }
2853 }
2854
2855 void ospf6_lsack_send_neighbor(struct event *thread)
2856 {
2857 struct ospf6_neighbor *on;
2858 struct ospf6_packet *op;
2859 uint16_t length = OSPF6_HEADER_SIZE;
2860
2861 on = (struct ospf6_neighbor *)EVENT_ARG(thread);
2862
2863 if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
2864 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND_HDR))
2865 zlog_debug("Quit to send LSAck to neighbor %s state %s",
2866 on->name,
2867 ospf6_neighbor_state_str[on->state]);
2868 return;
2869 }
2870
2871 /* if we have nothing to send, return */
2872 if (on->lsack_list->count == 0)
2873 return;
2874
2875 op = ospf6_packet_new(on->ospf6_if->ifmtu);
2876 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSACK, on->ospf6_if, op->s);
2877
2878 length += ospf6_make_lsack_neighbor(on, &op);
2879
2880 if (length == OSPF6_HEADER_SIZE) {
2881 ospf6_packet_free(op);
2882 return;
2883 }
2884
2885 /* Fill OSPF header. */
2886 ospf6_fill_header(on->ospf6_if, op->s, length);
2887
2888 /* Set packet length, dst and queue to FIFO. */
2889 op->length = length;
2890 op->dst = on->linklocal_addr;
2891 ospf6_fill_hdr_checksum(on->ospf6_if, op);
2892 ospf6_packet_add(on->ospf6_if, op);
2893 OSPF6_MESSAGE_WRITE_ON(on->ospf6_if);
2894
2895 if (on->lsack_list->count > 0)
2896 event_add_event(master, ospf6_lsack_send_neighbor, on, 0,
2897 &on->thread_send_lsack);
2898 }
2899
2900 static uint16_t ospf6_make_lsack_interface(struct ospf6_interface *oi,
2901 struct ospf6_packet *op)
2902 {
2903 uint16_t length = 0;
2904 struct ospf6_lsa *lsa, *lsanext;
2905
2906 for (ALL_LSDB(oi->lsack_list, lsa, lsanext)) {
2907 if ((length + sizeof(struct ospf6_lsa_header)
2908 + OSPF6_HEADER_SIZE)
2909 > ospf6_packet_max(oi)) {
2910 /* if we run out of packet size/space here,
2911 better to try again soon. */
2912 EVENT_OFF(oi->thread_send_lsack);
2913 event_add_event(master, ospf6_lsack_send_interface, oi,
2914 0, &oi->thread_send_lsack);
2915
2916 ospf6_lsa_unlock(lsa);
2917 if (lsanext)
2918 ospf6_lsa_unlock(lsanext);
2919 break;
2920 }
2921 ospf6_lsa_age_update_to_send(lsa, oi->transdelay);
2922 stream_put(op->s, lsa->header, sizeof(struct ospf6_lsa_header));
2923 length += sizeof(struct ospf6_lsa_header);
2924
2925 assert(lsa->lock == 2);
2926 ospf6_lsdb_remove(lsa, oi->lsack_list);
2927 }
2928 return length;
2929 }
2930
2931 void ospf6_lsack_send_interface(struct event *thread)
2932 {
2933 struct ospf6_interface *oi;
2934 struct ospf6_packet *op;
2935 uint16_t length = OSPF6_HEADER_SIZE;
2936
2937 oi = (struct ospf6_interface *)EVENT_ARG(thread);
2938
2939 if (oi->state <= OSPF6_INTERFACE_WAITING) {
2940 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND_HDR))
2941 zlog_debug(
2942 "Quit to send LSAck to interface %s state %s",
2943 oi->interface->name,
2944 ospf6_interface_state_str[oi->state]);
2945 return;
2946 }
2947
2948 /* if we have nothing to send, return */
2949 if (oi->lsack_list->count == 0)
2950 return;
2951
2952 op = ospf6_packet_new(oi->ifmtu);
2953 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSACK, oi, op->s);
2954
2955 length += ospf6_make_lsack_interface(oi, op);
2956
2957 if (length == OSPF6_HEADER_SIZE) {
2958 ospf6_packet_free(op);
2959 return;
2960 }
2961 /* Fill OSPF header. */
2962 ospf6_fill_header(oi, op->s, length);
2963
2964 /* Set packet length, dst and queue to FIFO. */
2965 op->length = length;
2966 if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT)
2967 || (oi->state == OSPF6_INTERFACE_DR)
2968 || (oi->state == OSPF6_INTERFACE_BDR))
2969 op->dst = allspfrouters6;
2970 else
2971 op->dst = alldrouters6;
2972
2973 ospf6_fill_hdr_checksum(oi, op);
2974 ospf6_packet_add(oi, op);
2975 OSPF6_MESSAGE_WRITE_ON(oi);
2976
2977 if (oi->lsack_list->count > 0)
2978 event_add_event(master, ospf6_lsack_send_interface, oi, 0,
2979 &oi->thread_send_lsack);
2980 }
2981
2982 /* Commands */
2983 DEFUN(debug_ospf6_message, debug_ospf6_message_cmd,
2984 "debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv|send-hdr|recv-hdr>]",
2985 DEBUG_STR OSPF6_STR
2986 "Debug OSPFv3 message\n"
2987 "Debug Unknown message\n"
2988 "Debug Hello message\n"
2989 "Debug Database Description message\n"
2990 "Debug Link State Request message\n"
2991 "Debug Link State Update message\n"
2992 "Debug Link State Acknowledgement message\n"
2993 "Debug All message\n"
2994 "Debug only sending message, entire packet\n"
2995 "Debug only receiving message, entire packet\n"
2996 "Debug only sending message, header only\n"
2997 "Debug only receiving message, header only\n")
2998 {
2999 int idx_packet = 3;
3000 int idx_send_recv = 4;
3001 unsigned char level = 0;
3002 int type = 0;
3003 int i;
3004
3005 /* check type */
3006 if (!strncmp(argv[idx_packet]->arg, "u", 1))
3007 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
3008 else if (!strncmp(argv[idx_packet]->arg, "h", 1))
3009 type = OSPF6_MESSAGE_TYPE_HELLO;
3010 else if (!strncmp(argv[idx_packet]->arg, "d", 1))
3011 type = OSPF6_MESSAGE_TYPE_DBDESC;
3012 else if (!strncmp(argv[idx_packet]->arg, "lsr", 3))
3013 type = OSPF6_MESSAGE_TYPE_LSREQ;
3014 else if (!strncmp(argv[idx_packet]->arg, "lsu", 3))
3015 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
3016 else if (!strncmp(argv[idx_packet]->arg, "lsa", 3))
3017 type = OSPF6_MESSAGE_TYPE_LSACK;
3018 else if (!strncmp(argv[idx_packet]->arg, "a", 1))
3019 type = OSPF6_MESSAGE_TYPE_ALL;
3020
3021 if (argc == 4)
3022 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
3023 else if (!strncmp(argv[idx_send_recv]->arg, "send-h", 6))
3024 level = OSPF6_DEBUG_MESSAGE_SEND_HDR;
3025 else if (!strncmp(argv[idx_send_recv]->arg, "s", 1))
3026 level = OSPF6_DEBUG_MESSAGE_SEND;
3027 else if (!strncmp(argv[idx_send_recv]->arg, "recv-h", 6))
3028 level = OSPF6_DEBUG_MESSAGE_RECV_HDR;
3029 else if (!strncmp(argv[idx_send_recv]->arg, "r", 1))
3030 level = OSPF6_DEBUG_MESSAGE_RECV;
3031
3032 if (type == OSPF6_MESSAGE_TYPE_ALL) {
3033 for (i = 0; i < 6; i++)
3034 OSPF6_DEBUG_MESSAGE_ON(i, level);
3035 } else
3036 OSPF6_DEBUG_MESSAGE_ON(type, level);
3037
3038 return CMD_SUCCESS;
3039 }
3040
3041 DEFUN(no_debug_ospf6_message, no_debug_ospf6_message_cmd,
3042 "no debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv|send-hdr|recv-hdr>]",
3043 NO_STR DEBUG_STR OSPF6_STR
3044 "Debug OSPFv3 message\n"
3045 "Debug Unknown message\n"
3046 "Debug Hello message\n"
3047 "Debug Database Description message\n"
3048 "Debug Link State Request message\n"
3049 "Debug Link State Update message\n"
3050 "Debug Link State Acknowledgement message\n"
3051 "Debug All message\n"
3052 "Debug only sending message, entire pkt\n"
3053 "Debug only receiving message, entire pkt\n"
3054 "Debug only sending message, header only\n"
3055 "Debug only receiving message, header only\n")
3056 {
3057 int idx_packet = 4;
3058 int idx_send_recv = 5;
3059 unsigned char level = 0;
3060 int type = 0;
3061 int i;
3062
3063 /* check type */
3064 if (!strncmp(argv[idx_packet]->arg, "u", 1))
3065 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
3066 else if (!strncmp(argv[idx_packet]->arg, "h", 1))
3067 type = OSPF6_MESSAGE_TYPE_HELLO;
3068 else if (!strncmp(argv[idx_packet]->arg, "d", 1))
3069 type = OSPF6_MESSAGE_TYPE_DBDESC;
3070 else if (!strncmp(argv[idx_packet]->arg, "lsr", 3))
3071 type = OSPF6_MESSAGE_TYPE_LSREQ;
3072 else if (!strncmp(argv[idx_packet]->arg, "lsu", 3))
3073 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
3074 else if (!strncmp(argv[idx_packet]->arg, "lsa", 3))
3075 type = OSPF6_MESSAGE_TYPE_LSACK;
3076 else if (!strncmp(argv[idx_packet]->arg, "a", 1))
3077 type = OSPF6_MESSAGE_TYPE_ALL;
3078
3079 if (argc == 5)
3080 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV
3081 | OSPF6_DEBUG_MESSAGE_SEND_HDR
3082 | OSPF6_DEBUG_MESSAGE_RECV_HDR;
3083 else if (!strncmp(argv[idx_send_recv]->arg, "send-h", 6))
3084 level = OSPF6_DEBUG_MESSAGE_SEND_HDR;
3085 else if (!strncmp(argv[idx_send_recv]->arg, "s", 1))
3086 level = OSPF6_DEBUG_MESSAGE_SEND;
3087 else if (!strncmp(argv[idx_send_recv]->arg, "recv-h", 6))
3088 level = OSPF6_DEBUG_MESSAGE_RECV_HDR;
3089 else if (!strncmp(argv[idx_send_recv]->arg, "r", 1))
3090 level = OSPF6_DEBUG_MESSAGE_RECV;
3091
3092 if (type == OSPF6_MESSAGE_TYPE_ALL) {
3093 for (i = 0; i < 6; i++)
3094 OSPF6_DEBUG_MESSAGE_OFF(i, level);
3095 } else
3096 OSPF6_DEBUG_MESSAGE_OFF(type, level);
3097
3098 return CMD_SUCCESS;
3099 }
3100
3101
3102 int config_write_ospf6_debug_message(struct vty *vty)
3103 {
3104 const char *type_str[] = {"unknown", "hello", "dbdesc",
3105 "lsreq", "lsupdate", "lsack"};
3106 unsigned char s = 0, r = 0, sh = 0, rh = 0;
3107 int i;
3108
3109 for (i = 0; i < 6; i++) {
3110 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND))
3111 s |= 1 << i;
3112 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV))
3113 r |= 1 << i;
3114 }
3115
3116 for (i = 0; i < 6; i++) {
3117 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND_HDR))
3118 sh |= 1 << i;
3119 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV_HDR))
3120 rh |= 1 << i;
3121 }
3122
3123 if (s == 0x3f && r == 0x3f) {
3124 vty_out(vty, "debug ospf6 message all\n");
3125 return 0;
3126 }
3127
3128 if (s == 0x3f && r == 0) {
3129 vty_out(vty, "debug ospf6 message all send\n");
3130 return 0;
3131 } else if (s == 0 && r == 0x3f) {
3132 vty_out(vty, "debug ospf6 message all recv\n");
3133 return 0;
3134 }
3135
3136 if (sh == 0x3f && rh == 0) {
3137 vty_out(vty, "debug ospf6 message all send-hdr\n");
3138 return 0;
3139 } else if (sh == 0 && rh == 0x3f) {
3140 vty_out(vty, "debug ospf6 message all recv-hdr\n");
3141 return 0;
3142 }
3143
3144 /* Unknown message is logged by default */
3145 if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, SEND)
3146 && !IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
3147 vty_out(vty, "no debug ospf6 message unknown\n");
3148 else if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
3149 vty_out(vty, "no debug ospf6 message unknown send\n");
3150 else if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
3151 vty_out(vty, "no debug ospf6 message unknown recv\n");
3152
3153 for (i = 1; i < 6; i++) {
3154 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND)
3155 && IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV)) {
3156 vty_out(vty, "debug ospf6 message %s\n", type_str[i]);
3157 continue;
3158 }
3159
3160 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND))
3161 vty_out(vty, "debug ospf6 message %s send\n",
3162 type_str[i]);
3163 else if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND_HDR))
3164 vty_out(vty, "debug ospf6 message %s send-hdr\n",
3165 type_str[i]);
3166
3167 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV))
3168 vty_out(vty, "debug ospf6 message %s recv\n",
3169 type_str[i]);
3170 else if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV_HDR))
3171 vty_out(vty, "debug ospf6 message %s recv-hdr\n",
3172 type_str[i]);
3173 }
3174
3175 return 0;
3176 }
3177
3178 void install_element_ospf6_debug_message(void)
3179 {
3180 install_element(ENABLE_NODE, &debug_ospf6_message_cmd);
3181 install_element(ENABLE_NODE, &no_debug_ospf6_message_cmd);
3182 install_element(CONFIG_NODE, &debug_ospf6_message_cmd);
3183 install_element(CONFIG_NODE, &no_debug_ospf6_message_cmd);
3184 }