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