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