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