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