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