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