Annotation of embedaddon/quagga/ospf6d/ospf6_intra.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2003 Yasuhiro Ohara
3: *
4: * This file is part of GNU Zebra.
5: *
6: * GNU Zebra is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2, or (at your option) any
9: * later version.
10: *
11: * GNU Zebra is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with GNU Zebra; see the file COPYING. If not, write to the
18: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19: * Boston, MA 02111-1307, USA.
20: */
21:
22: #include <zebra.h>
23:
24: #include "log.h"
25: #include "linklist.h"
26: #include "thread.h"
27: #include "memory.h"
28: #include "if.h"
29: #include "prefix.h"
30: #include "table.h"
31: #include "vty.h"
32: #include "command.h"
33:
34: #include "ospf6_proto.h"
35: #include "ospf6_message.h"
36: #include "ospf6_route.h"
37: #include "ospf6_lsa.h"
38: #include "ospf6_lsdb.h"
39:
40: #include "ospf6_top.h"
41: #include "ospf6_area.h"
42: #include "ospf6_interface.h"
43: #include "ospf6_neighbor.h"
44: #include "ospf6_intra.h"
45: #include "ospf6_asbr.h"
46: #include "ospf6_abr.h"
47: #include "ospf6_flood.h"
48: #include "ospf6d.h"
49:
50:
51: unsigned char conf_debug_ospf6_brouter = 0;
52: u_int32_t conf_debug_ospf6_brouter_specific_router_id;
53: u_int32_t conf_debug_ospf6_brouter_specific_area_id;
54:
55: /******************************/
56: /* RFC2740 3.4.3.1 Router-LSA */
57: /******************************/
58:
59: static int
60: ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
61: {
62: char *start, *end, *current;
63: char buf[32], name[32], bits[16], options[32];
64: struct ospf6_router_lsa *router_lsa;
65: struct ospf6_router_lsdesc *lsdesc;
66:
67: router_lsa = (struct ospf6_router_lsa *)
68: ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
69:
70: ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits));
71: ospf6_options_printbuf (router_lsa->options, options, sizeof (options));
72: vty_out (vty, " Bits: %s Options: %s%s", bits, options, VNL);
73:
74: start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
75: end = (char *) lsa->header + ntohs (lsa->header->length);
76: for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end;
77: current += sizeof (struct ospf6_router_lsdesc))
78: {
79: lsdesc = (struct ospf6_router_lsdesc *) current;
80:
81: if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT)
82: snprintf (name, sizeof (name), "Point-To-Point");
83: else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK)
84: snprintf (name, sizeof (name), "Transit-Network");
85: else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK)
86: snprintf (name, sizeof (name), "Stub-Network");
87: else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK)
88: snprintf (name, sizeof (name), "Virtual-Link");
89: else
90: snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
91:
92: vty_out (vty, " Type: %s Metric: %d%s",
93: name, ntohs (lsdesc->metric), VNL);
94: vty_out (vty, " Interface ID: %s%s",
95: inet_ntop (AF_INET, &lsdesc->interface_id,
96: buf, sizeof (buf)), VNL);
97: vty_out (vty, " Neighbor Interface ID: %s%s",
98: inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
99: buf, sizeof (buf)), VNL);
100: vty_out (vty, " Neighbor Router ID: %s%s",
101: inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
102: buf, sizeof (buf)), VNL);
103: }
104: return 0;
105: }
106:
107: int
108: ospf6_router_lsa_originate (struct thread *thread)
109: {
110: struct ospf6_area *oa;
111:
112: char buffer [OSPF6_MAX_LSASIZE];
113: struct ospf6_lsa_header *lsa_header;
114: struct ospf6_lsa *lsa;
115:
116: u_int32_t link_state_id = 0;
117: struct listnode *node, *nnode;
118: struct listnode *j;
119: struct ospf6_interface *oi;
120: struct ospf6_neighbor *on, *drouter = NULL;
121: struct ospf6_router_lsa *router_lsa;
122: struct ospf6_router_lsdesc *lsdesc;
123: u_int16_t type;
124: u_int32_t router;
125: int count;
126:
127: oa = (struct ospf6_area *) THREAD_ARG (thread);
128: oa->thread_router_lsa = NULL;
129:
130: if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
131: zlog_debug ("Originate Router-LSA for Area %s", oa->name);
132:
133: memset (buffer, 0, sizeof (buffer));
134: lsa_header = (struct ospf6_lsa_header *) buffer;
135: router_lsa = (struct ospf6_router_lsa *)
136: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
137:
138: OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
139: OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
140: OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
141: OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
142: OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
143: OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
144:
145: if (ospf6_is_router_abr (ospf6))
146: SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
147: else
148: UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
149: if (ospf6_asbr_is_asbr (ospf6))
150: SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
151: else
152: UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
153: UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
154: UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
155:
156: /* describe links for each interfaces */
157: lsdesc = (struct ospf6_router_lsdesc *)
158: ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
159:
160: for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
161: {
162: /* Interfaces in state Down or Loopback are not described */
163: if (oi->state == OSPF6_INTERFACE_DOWN ||
164: oi->state == OSPF6_INTERFACE_LOOPBACK)
165: continue;
166:
167: /* Nor are interfaces without any full adjacencies described */
168: count = 0;
169: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
170: if (on->state == OSPF6_NEIGHBOR_FULL)
171: count++;
172:
173: if (count == 0)
174: continue;
175:
176: /* Multiple Router-LSA instance according to size limit setting */
177: if ( (oa->router_lsa_size_limit != 0)
178: && ((caddr_t) lsdesc + sizeof (struct ospf6_router_lsdesc) -
179: /* XXX warning: comparison between signed and unsigned */
180: (caddr_t) buffer > oa->router_lsa_size_limit))
181: {
182: if ((caddr_t) lsdesc == (caddr_t) router_lsa +
183: sizeof (struct ospf6_router_lsa))
184: {
185: if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
186: zlog_debug ("Size limit setting for Router-LSA too short");
187: return 0;
188: }
189:
190: /* Fill LSA Header */
191: lsa_header->age = 0;
192: lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
193: lsa_header->id = htonl (link_state_id);
194: lsa_header->adv_router = oa->ospf6->router_id;
195: lsa_header->seqnum =
196: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
197: lsa_header->adv_router, oa->lsdb);
198: lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
199:
200: /* LSA checksum */
201: ospf6_lsa_checksum (lsa_header);
202:
203: /* create LSA */
204: lsa = ospf6_lsa_create (lsa_header);
205:
206: /* Originate */
207: ospf6_lsa_originate_area (lsa, oa);
208:
209: /* Reset setting for consecutive origination */
210: memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
211: 0, (caddr_t) lsdesc - (caddr_t) router_lsa);
212: lsdesc = (struct ospf6_router_lsdesc *)
213: ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
214: link_state_id ++;
215: }
216:
217: /* Point-to-Point interfaces */
218: if (if_is_pointopoint (oi->interface))
219: {
220: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
221: {
222: if (on->state != OSPF6_NEIGHBOR_FULL)
223: continue;
224:
225: lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
226: lsdesc->metric = htons (oi->cost);
227: lsdesc->interface_id = htonl (oi->interface->ifindex);
228: lsdesc->neighbor_interface_id = htonl (on->ifindex);
229: lsdesc->neighbor_router_id = on->router_id;
230:
231: lsdesc++;
232: }
233: }
234:
235: /* Broadcast and NBMA interfaces */
236: if (if_is_broadcast (oi->interface))
237: {
238: /* If this router is not DR,
239: and If this router not fully adjacent with DR,
240: this interface is not transit yet: ignore. */
241: if (oi->state != OSPF6_INTERFACE_DR)
242: {
243: drouter = ospf6_neighbor_lookup (oi->drouter, oi);
244: if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
245: continue;
246: }
247:
248: lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
249: lsdesc->metric = htons (oi->cost);
250: lsdesc->interface_id = htonl (oi->interface->ifindex);
251: if (oi->state != OSPF6_INTERFACE_DR)
252: {
253: lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
254: lsdesc->neighbor_router_id = drouter->router_id;
255: }
256: else
257: {
258: lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
259: lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
260: }
261:
262: lsdesc++;
263: }
264:
265: /* Virtual links */
266: /* xxx */
267: /* Point-to-Multipoint interfaces */
268: /* xxx */
269: }
270:
271: if ((caddr_t) lsdesc != (caddr_t) router_lsa +
272: sizeof (struct ospf6_router_lsa))
273: {
274: /* Fill LSA Header */
275: lsa_header->age = 0;
276: lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
277: lsa_header->id = htonl (link_state_id);
278: lsa_header->adv_router = oa->ospf6->router_id;
279: lsa_header->seqnum =
280: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
281: lsa_header->adv_router, oa->lsdb);
282: lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
283:
284: /* LSA checksum */
285: ospf6_lsa_checksum (lsa_header);
286:
287: /* create LSA */
288: lsa = ospf6_lsa_create (lsa_header);
289:
290: /* Originate */
291: ospf6_lsa_originate_area (lsa, oa);
292:
293: link_state_id ++;
294: }
295: else
296: {
297: if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
298: zlog_debug ("Nothing to describe in Router-LSA, suppress");
299: }
300:
301: /* Do premature-aging of rest, undesired Router-LSAs */
302: type = ntohs (OSPF6_LSTYPE_ROUTER);
303: router = oa->ospf6->router_id;
304: for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
305: lsa = ospf6_lsdb_type_router_next (type, router, lsa))
306: {
307: if (ntohl (lsa->header->id) < link_state_id)
308: continue;
309: ospf6_lsa_purge (lsa);
310: }
311:
312: return 0;
313: }
314:
315: /*******************************/
316: /* RFC2740 3.4.3.2 Network-LSA */
317: /*******************************/
318:
319: static int
320: ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
321: {
322: char *start, *end, *current;
323: struct ospf6_network_lsa *network_lsa;
324: struct ospf6_network_lsdesc *lsdesc;
325: char buf[128], options[32];
326:
327: network_lsa = (struct ospf6_network_lsa *)
328: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
329:
330: ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
331: vty_out (vty, " Options: %s%s", options, VNL);
332:
333: start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
334: end = (char *) lsa->header + ntohs (lsa->header->length);
335: for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
336: current += sizeof (struct ospf6_network_lsdesc))
337: {
338: lsdesc = (struct ospf6_network_lsdesc *) current;
339: inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
340: vty_out (vty, " Attached Router: %s%s", buf, VNL);
341: }
342: return 0;
343: }
344:
345: int
346: ospf6_network_lsa_originate (struct thread *thread)
347: {
348: struct ospf6_interface *oi;
349:
350: char buffer [OSPF6_MAX_LSASIZE];
351: struct ospf6_lsa_header *lsa_header;
352:
353: int count;
354: struct ospf6_lsa *old, *lsa;
355: struct ospf6_network_lsa *network_lsa;
356: struct ospf6_network_lsdesc *lsdesc;
357: struct ospf6_neighbor *on;
358: struct ospf6_link_lsa *link_lsa;
359: struct listnode *i;
360: u_int16_t type;
361:
362: oi = (struct ospf6_interface *) THREAD_ARG (thread);
363: oi->thread_network_lsa = NULL;
364:
365: /* The interface must be enabled until here. A Network-LSA of a
366: disabled interface (but was once enabled) should be flushed
367: by ospf6_lsa_refresh (), and does not come here. */
368: assert (oi->area);
369:
370: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
371: htonl (oi->interface->ifindex),
372: oi->area->ospf6->router_id, oi->area->lsdb);
373:
374: /* Do not originate Network-LSA if not DR */
375: if (oi->state != OSPF6_INTERFACE_DR)
376: {
377: if (old)
378: ospf6_lsa_purge (old);
379: return 0;
380: }
381:
382: if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
383: zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);
384:
385: /* If none of neighbor is adjacent to us */
386: count = 0;
387:
388: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
389: if (on->state == OSPF6_NEIGHBOR_FULL)
390: count++;
391:
392: if (count == 0)
393: {
394: if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
395: zlog_debug ("Interface stub, ignore");
396: if (old)
397: ospf6_lsa_purge (old);
398: return 0;
399: }
400:
401: /* prepare buffer */
402: memset (buffer, 0, sizeof (buffer));
403: lsa_header = (struct ospf6_lsa_header *) buffer;
404: network_lsa = (struct ospf6_network_lsa *)
405: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
406:
407: /* Collect the interface's Link-LSAs to describe
408: network's optional capabilities */
409: type = htons (OSPF6_LSTYPE_LINK);
410: for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
411: lsa = ospf6_lsdb_type_next (type, lsa))
412: {
413: link_lsa = (struct ospf6_link_lsa *)
414: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
415: network_lsa->options[0] |= link_lsa->options[0];
416: network_lsa->options[1] |= link_lsa->options[1];
417: network_lsa->options[2] |= link_lsa->options[2];
418: }
419:
420: lsdesc = (struct ospf6_network_lsdesc *)
421: ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));
422:
423: /* set Link Description to the router itself */
424: lsdesc->router_id = oi->area->ospf6->router_id;
425: lsdesc++;
426:
427: /* Walk through the neighbors */
428: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
429: {
430: if (on->state != OSPF6_NEIGHBOR_FULL)
431: continue;
432:
433: /* set this neighbor's Router-ID to LSA */
434: lsdesc->router_id = on->router_id;
435: lsdesc++;
436: }
437:
438: /* Fill LSA Header */
439: lsa_header->age = 0;
440: lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
441: lsa_header->id = htonl (oi->interface->ifindex);
442: lsa_header->adv_router = oi->area->ospf6->router_id;
443: lsa_header->seqnum =
444: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
445: lsa_header->adv_router, oi->area->lsdb);
446: lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
447:
448: /* LSA checksum */
449: ospf6_lsa_checksum (lsa_header);
450:
451: /* create LSA */
452: lsa = ospf6_lsa_create (lsa_header);
453:
454: /* Originate */
455: ospf6_lsa_originate_area (lsa, oi->area);
456:
457: return 0;
458: }
459:
460:
461: /****************************/
462: /* RFC2740 3.4.3.6 Link-LSA */
463: /****************************/
464:
465: static int
466: ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
467: {
468: char *start, *end, *current;
469: struct ospf6_link_lsa *link_lsa;
470: int prefixnum;
471: char buf[128], options[32];
472: struct ospf6_prefix *prefix;
473: const char *p, *mc, *la, *nu;
474: struct in6_addr in6;
475:
476: link_lsa = (struct ospf6_link_lsa *)
477: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
478:
479: ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
480: inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
481: prefixnum = ntohl (link_lsa->prefix_num);
482:
483: vty_out (vty, " Priority: %d Options: %s%s",
484: link_lsa->priority, options, VNL);
485: vty_out (vty, " LinkLocal Address: %s%s", buf, VNL);
486: vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
487:
488: start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
489: end = (char *) lsa->header + ntohs (lsa->header->length);
490: for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
491: {
492: prefix = (struct ospf6_prefix *) current;
493: if (prefix->prefix_length == 0 ||
494: current + OSPF6_PREFIX_SIZE (prefix) > end)
495: break;
496:
497: p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
498: "P" : "--");
499: mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
500: "MC" : "--");
501: la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
502: "LA" : "--");
503: nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
504: "NU" : "--");
505: vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
506: p, mc, la, nu, VNL);
507:
508: memset (&in6, 0, sizeof (in6));
509: memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
510: OSPF6_PREFIX_SPACE (prefix->prefix_length));
511: inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
512: vty_out (vty, " Prefix: %s/%d%s",
513: buf, prefix->prefix_length, VNL);
514: }
515:
516: return 0;
517: }
518:
519: int
520: ospf6_link_lsa_originate (struct thread *thread)
521: {
522: struct ospf6_interface *oi;
523:
524: char buffer[OSPF6_MAX_LSASIZE];
525: struct ospf6_lsa_header *lsa_header;
526: struct ospf6_lsa *old, *lsa;
527:
528: struct ospf6_link_lsa *link_lsa;
529: struct ospf6_route *route;
530: struct ospf6_prefix *op;
531:
532: oi = (struct ospf6_interface *) THREAD_ARG (thread);
533: oi->thread_link_lsa = NULL;
534:
535: assert (oi->area);
536:
537: /* find previous LSA */
538: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
539: htonl (oi->interface->ifindex),
540: oi->area->ospf6->router_id, oi->lsdb);
541:
542: if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
543: {
544: if (old)
545: ospf6_lsa_purge (old);
546: return 0;
547: }
548:
549: if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
550: zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);
551:
552: /* can't make Link-LSA if linklocal address not set */
553: if (oi->linklocal_addr == NULL)
554: {
555: if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
556: zlog_debug ("No Linklocal address on %s, defer originating",
557: oi->interface->name);
558: if (old)
559: ospf6_lsa_purge (old);
560: return 0;
561: }
562:
563: /* prepare buffer */
564: memset (buffer, 0, sizeof (buffer));
565: lsa_header = (struct ospf6_lsa_header *) buffer;
566: link_lsa = (struct ospf6_link_lsa *)
567: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
568:
569: /* Fill Link-LSA */
570: link_lsa->priority = oi->priority;
571: memcpy (link_lsa->options, oi->area->options, 3);
572: memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
573: sizeof (struct in6_addr));
574: link_lsa->prefix_num = htonl (oi->route_connected->count);
575:
576: op = (struct ospf6_prefix *)
577: ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
578:
579: /* connected prefix to advertise */
580: for (route = ospf6_route_head (oi->route_connected); route;
581: route = ospf6_route_next (route))
582: {
583: op->prefix_length = route->prefix.prefixlen;
584: op->prefix_options = route->path.prefix_options;
585: op->prefix_metric = htons (0);
586: memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
587: OSPF6_PREFIX_SPACE (op->prefix_length));
588: op = OSPF6_PREFIX_NEXT (op);
589: }
590:
591: /* Fill LSA Header */
592: lsa_header->age = 0;
593: lsa_header->type = htons (OSPF6_LSTYPE_LINK);
594: lsa_header->id = htonl (oi->interface->ifindex);
595: lsa_header->adv_router = oi->area->ospf6->router_id;
596: lsa_header->seqnum =
597: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
598: lsa_header->adv_router, oi->lsdb);
599: lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
600:
601: /* LSA checksum */
602: ospf6_lsa_checksum (lsa_header);
603:
604: /* create LSA */
605: lsa = ospf6_lsa_create (lsa_header);
606:
607: /* Originate */
608: ospf6_lsa_originate_interface (lsa, oi);
609:
610: return 0;
611: }
612:
613:
614: /*****************************************/
615: /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
616: /*****************************************/
617:
618: static int
619: ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
620: {
621: char *start, *end, *current;
622: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
623: int prefixnum;
624: char buf[128];
625: struct ospf6_prefix *prefix;
626: char id[16], adv_router[16];
627: const char *p, *mc, *la, *nu;
628: struct in6_addr in6;
629:
630: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
631: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
632:
633: prefixnum = ntohs (intra_prefix_lsa->prefix_num);
634:
635: vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
636:
637: inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
638: inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
639: adv_router, sizeof (adv_router));
640: vty_out (vty, " Reference: %s Id: %s Adv: %s%s",
641: ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
642: VNL);
643:
644: start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
645: end = (char *) lsa->header + ntohs (lsa->header->length);
646: for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
647: {
648: prefix = (struct ospf6_prefix *) current;
649: if (prefix->prefix_length == 0 ||
650: current + OSPF6_PREFIX_SIZE (prefix) > end)
651: break;
652:
653: p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
654: "P" : "--");
655: mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
656: "MC" : "--");
657: la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
658: "LA" : "--");
659: nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
660: "NU" : "--");
661: vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
662: p, mc, la, nu, VNL);
663:
664: memset (&in6, 0, sizeof (in6));
665: memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
666: OSPF6_PREFIX_SPACE (prefix->prefix_length));
667: inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
668: vty_out (vty, " Prefix: %s/%d%s",
669: buf, prefix->prefix_length, VNL);
670: }
671:
672: return 0;
673: }
674:
675: int
676: ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
677: {
678: struct ospf6_area *oa;
679:
680: char buffer[OSPF6_MAX_LSASIZE];
681: struct ospf6_lsa_header *lsa_header;
682: struct ospf6_lsa *old, *lsa;
683:
684: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
685: struct ospf6_interface *oi;
686: struct ospf6_neighbor *on;
687: struct ospf6_route *route;
688: struct ospf6_prefix *op;
689: struct listnode *i, *j;
690: int full_count = 0;
691: unsigned short prefix_num = 0;
692: char buf[BUFSIZ];
693: struct ospf6_route_table *route_advertise;
694:
695: oa = (struct ospf6_area *) THREAD_ARG (thread);
696: oa->thread_intra_prefix_lsa = NULL;
697:
698: /* find previous LSA */
699: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
700: htonl (0), oa->ospf6->router_id, oa->lsdb);
701:
702: if (! IS_AREA_ENABLED (oa))
703: {
704: if (old)
705: ospf6_lsa_purge (old);
706: return 0;
707: }
708:
709: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
710: zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
711: oa->name);
712:
713: /* prepare buffer */
714: memset (buffer, 0, sizeof (buffer));
715: lsa_header = (struct ospf6_lsa_header *) buffer;
716: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
717: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
718:
719: /* Fill Intra-Area-Prefix-LSA */
720: intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
721: intra_prefix_lsa->ref_id = htonl (0);
722: intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
723:
724: route_advertise = ospf6_route_table_create (0, 0);
725:
726: for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
727: {
728: if (oi->state == OSPF6_INTERFACE_DOWN)
729: {
730: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
731: zlog_debug (" Interface %s is down, ignore", oi->interface->name);
732: continue;
733: }
734:
735: full_count = 0;
736:
737: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
738: if (on->state == OSPF6_NEIGHBOR_FULL)
739: full_count++;
740:
741: if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
742: oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
743: full_count != 0)
744: {
745: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
746: zlog_debug (" Interface %s is not stub, ignore",
747: oi->interface->name);
748: continue;
749: }
750:
751: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
752: zlog_debug (" Interface %s:", oi->interface->name);
753:
754: /* connected prefix to advertise */
755: for (route = ospf6_route_head (oi->route_connected); route;
756: route = ospf6_route_best_next (route))
757: {
758: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
759: {
760: prefix2str (&route->prefix, buf, sizeof (buf));
761: zlog_debug (" include %s", buf);
762: }
763: ospf6_route_add (ospf6_route_copy (route), route_advertise);
764: }
765: }
766:
767: if (route_advertise->count == 0)
768: {
769: if (old)
770: ospf6_lsa_purge (old);
771: ospf6_route_table_delete (route_advertise);
772: return 0;
773: }
774:
775: /* put prefixes to advertise */
776: prefix_num = 0;
777: op = (struct ospf6_prefix *)
778: ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
779: for (route = ospf6_route_head (route_advertise); route;
780: route = ospf6_route_best_next (route))
781: {
782: op->prefix_length = route->prefix.prefixlen;
783: op->prefix_options = route->path.prefix_options;
784: op->prefix_metric = htons (route->path.cost);
785: memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
786: OSPF6_PREFIX_SPACE (op->prefix_length));
787: op = OSPF6_PREFIX_NEXT (op);
788: prefix_num++;
789: }
790:
791: ospf6_route_table_delete (route_advertise);
792:
793: if (prefix_num == 0)
794: {
795: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
796: zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
797: return 0;
798: }
799:
800: intra_prefix_lsa->prefix_num = htons (prefix_num);
801:
802: /* Fill LSA Header */
803: lsa_header->age = 0;
804: lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
805: lsa_header->id = htonl (0);
806: lsa_header->adv_router = oa->ospf6->router_id;
807: lsa_header->seqnum =
808: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
809: lsa_header->adv_router, oa->lsdb);
810: lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
811:
812: /* LSA checksum */
813: ospf6_lsa_checksum (lsa_header);
814:
815: /* create LSA */
816: lsa = ospf6_lsa_create (lsa_header);
817:
818: /* Originate */
819: ospf6_lsa_originate_area (lsa, oa);
820:
821: return 0;
822: }
823:
824:
825: int
826: ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
827: {
828: struct ospf6_interface *oi;
829:
830: char buffer[OSPF6_MAX_LSASIZE];
831: struct ospf6_lsa_header *lsa_header;
832: struct ospf6_lsa *old, *lsa;
833:
834: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
835: struct ospf6_neighbor *on;
836: struct ospf6_route *route;
837: struct ospf6_prefix *op;
838: struct listnode *i;
839: int full_count = 0;
840: unsigned short prefix_num = 0;
841: struct ospf6_route_table *route_advertise;
842: struct ospf6_link_lsa *link_lsa;
843: char *start, *end, *current;
844: u_int16_t type;
845: char buf[BUFSIZ];
846:
847: oi = (struct ospf6_interface *) THREAD_ARG (thread);
848: oi->thread_intra_prefix_lsa = NULL;
849:
850: assert (oi->area);
851:
852: /* find previous LSA */
853: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
854: htonl (oi->interface->ifindex),
855: oi->area->ospf6->router_id, oi->area->lsdb);
856:
857: if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
858: {
859: if (old)
860: ospf6_lsa_purge (old);
861: return 0;
862: }
863:
864: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
865: zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
866: oi->interface->name);
867:
868: /* prepare buffer */
869: memset (buffer, 0, sizeof (buffer));
870: lsa_header = (struct ospf6_lsa_header *) buffer;
871: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
872: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
873:
874: /* Fill Intra-Area-Prefix-LSA */
875: intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
876: intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
877: intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
878:
879: if (oi->state != OSPF6_INTERFACE_DR)
880: {
881: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
882: zlog_debug (" Interface is not DR");
883: if (old)
884: ospf6_lsa_purge (old);
885: return 0;
886: }
887:
888: full_count = 0;
889: for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
890: if (on->state == OSPF6_NEIGHBOR_FULL)
891: full_count++;
892:
893: if (full_count == 0)
894: {
895: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
896: zlog_debug (" Interface is stub");
897: if (old)
898: ospf6_lsa_purge (old);
899: return 0;
900: }
901:
902: /* connected prefix to advertise */
903: route_advertise = ospf6_route_table_create (0, 0);
904:
905: type = ntohs (OSPF6_LSTYPE_LINK);
906: for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
907: lsa = ospf6_lsdb_type_next (type, lsa))
908: {
909: if (OSPF6_LSA_IS_MAXAGE (lsa))
910: continue;
911:
912: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
913: zlog_debug (" include prefix from %s", lsa->name);
914:
915: if (lsa->header->adv_router != oi->area->ospf6->router_id)
916: {
917: on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
918: if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
919: {
920: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
921: zlog_debug (" Neighbor not found or not Full, ignore");
922: continue;
923: }
924: }
925:
926: link_lsa = (struct ospf6_link_lsa *)
927: ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
928:
929: prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
930: start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
931: end = (char *) lsa->header + ntohs (lsa->header->length);
932: for (current = start; current < end && prefix_num;
933: current += OSPF6_PREFIX_SIZE (op))
934: {
935: op = (struct ospf6_prefix *) current;
936: if (op->prefix_length == 0 ||
937: current + OSPF6_PREFIX_SIZE (op) > end)
938: break;
939:
940: route = ospf6_route_create ();
941:
942: route->type = OSPF6_DEST_TYPE_NETWORK;
943: route->prefix.family = AF_INET6;
944: route->prefix.prefixlen = op->prefix_length;
945: memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
946: memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
947: OSPF6_PREFIX_SPACE (op->prefix_length));
948:
949: route->path.origin.type = lsa->header->type;
950: route->path.origin.id = lsa->header->id;
951: route->path.origin.adv_router = lsa->header->adv_router;
952: route->path.options[0] = link_lsa->options[0];
953: route->path.options[1] = link_lsa->options[1];
954: route->path.options[2] = link_lsa->options[2];
955: route->path.prefix_options = op->prefix_options;
956: route->path.area_id = oi->area->area_id;
957: route->path.type = OSPF6_PATH_TYPE_INTRA;
958:
959: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
960: {
961: prefix2str (&route->prefix, buf, sizeof (buf));
962: zlog_debug (" include %s", buf);
963: }
964:
965: ospf6_route_add (route, route_advertise);
966: prefix_num--;
967: }
968: if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
969: zlog_debug ("Trailing garbage in %s", lsa->name);
970: }
971:
972: op = (struct ospf6_prefix *)
973: ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
974:
975: prefix_num = 0;
976: for (route = ospf6_route_head (route_advertise); route;
977: route = ospf6_route_best_next (route))
978: {
979: op->prefix_length = route->prefix.prefixlen;
980: op->prefix_options = route->path.prefix_options;
981: op->prefix_metric = htons (0);
982: memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
983: OSPF6_PREFIX_SPACE (op->prefix_length));
984: op = OSPF6_PREFIX_NEXT (op);
985: prefix_num++;
986: }
987:
988: ospf6_route_table_delete (route_advertise);
989:
990: if (prefix_num == 0)
991: {
992: if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
993: zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
994: return 0;
995: }
996:
997: intra_prefix_lsa->prefix_num = htons (prefix_num);
998:
999: /* Fill LSA Header */
1000: lsa_header->age = 0;
1001: lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1002: lsa_header->id = htonl (oi->interface->ifindex);
1003: lsa_header->adv_router = oi->area->ospf6->router_id;
1004: lsa_header->seqnum =
1005: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
1006: lsa_header->adv_router, oi->area->lsdb);
1007: lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
1008:
1009: /* LSA checksum */
1010: ospf6_lsa_checksum (lsa_header);
1011:
1012: /* create LSA */
1013: lsa = ospf6_lsa_create (lsa_header);
1014:
1015: /* Originate */
1016: ospf6_lsa_originate_area (lsa, oi->area);
1017:
1018: return 0;
1019: }
1020:
1021: void
1022: ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
1023: {
1024: struct ospf6_area *oa;
1025: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1026: struct prefix ls_prefix;
1027: struct ospf6_route *route, *ls_entry;
1028: int i, prefix_num;
1029: struct ospf6_prefix *op;
1030: char *start, *current, *end;
1031: char buf[64];
1032:
1033: if (OSPF6_LSA_IS_MAXAGE (lsa))
1034: return;
1035:
1036: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1037: zlog_debug ("%s found", lsa->name);
1038:
1039: oa = OSPF6_AREA (lsa->lsdb->data);
1040:
1041: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1042: OSPF6_LSA_HEADER_END (lsa->header);
1043: if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
1044: ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1045: htonl (0), &ls_prefix);
1046: else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
1047: ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1048: intra_prefix_lsa->ref_id, &ls_prefix);
1049: else
1050: {
1051: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1052: zlog_debug ("Unknown reference LS-type: %#hx",
1053: ntohs (intra_prefix_lsa->ref_type));
1054: return;
1055: }
1056:
1057: ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
1058: if (ls_entry == NULL)
1059: {
1060: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1061: {
1062: ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
1063: zlog_debug ("LS entry does not exist: %s", buf);
1064: }
1065: return;
1066: }
1067:
1068: prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1069: start = (caddr_t) intra_prefix_lsa +
1070: sizeof (struct ospf6_intra_prefix_lsa);
1071: end = OSPF6_LSA_END (lsa->header);
1072: for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1073: {
1074: op = (struct ospf6_prefix *) current;
1075: if (prefix_num == 0)
1076: break;
1077: if (end < current + OSPF6_PREFIX_SIZE (op))
1078: break;
1079:
1080: route = ospf6_route_create ();
1081:
1082: memset (&route->prefix, 0, sizeof (struct prefix));
1083: route->prefix.family = AF_INET6;
1084: route->prefix.prefixlen = op->prefix_length;
1085: ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);
1086:
1087: route->type = OSPF6_DEST_TYPE_NETWORK;
1088: route->path.origin.type = lsa->header->type;
1089: route->path.origin.id = lsa->header->id;
1090: route->path.origin.adv_router = lsa->header->adv_router;
1091: route->path.prefix_options = op->prefix_options;
1092: route->path.area_id = oa->area_id;
1093: route->path.type = OSPF6_PATH_TYPE_INTRA;
1094: route->path.metric_type = 1;
1095: route->path.cost = ls_entry->path.cost +
1096: ntohs (op->prefix_metric);
1097:
1098: for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) &&
1099: i < OSPF6_MULTI_PATH_LIMIT; i++)
1100: ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
1101:
1102: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1103: {
1104: prefix2str (&route->prefix, buf, sizeof (buf));
1105: zlog_debug (" add %s", buf);
1106: }
1107:
1108: ospf6_route_add (route, oa->route_table);
1109: prefix_num--;
1110: }
1111:
1112: if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1113: zlog_debug ("Trailing garbage ignored");
1114: }
1115:
1116: void
1117: ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
1118: {
1119: struct ospf6_area *oa;
1120: struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1121: struct prefix prefix;
1122: struct ospf6_route *route;
1123: int prefix_num;
1124: struct ospf6_prefix *op;
1125: char *start, *current, *end;
1126: char buf[64];
1127:
1128: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1129: zlog_debug ("%s disappearing", lsa->name);
1130:
1131: oa = OSPF6_AREA (lsa->lsdb->data);
1132:
1133: intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1134: OSPF6_LSA_HEADER_END (lsa->header);
1135:
1136: prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1137: start = (caddr_t) intra_prefix_lsa +
1138: sizeof (struct ospf6_intra_prefix_lsa);
1139: end = OSPF6_LSA_END (lsa->header);
1140: for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1141: {
1142: op = (struct ospf6_prefix *) current;
1143: if (prefix_num == 0)
1144: break;
1145: if (end < current + OSPF6_PREFIX_SIZE (op))
1146: break;
1147: prefix_num--;
1148:
1149: memset (&prefix, 0, sizeof (struct prefix));
1150: prefix.family = AF_INET6;
1151: prefix.prefixlen = op->prefix_length;
1152: ospf6_prefix_in6_addr (&prefix.u.prefix6, op);
1153:
1154: route = ospf6_route_lookup (&prefix, oa->route_table);
1155: if (route == NULL)
1156: continue;
1157:
1158: for (ospf6_route_lock (route);
1159: route && ospf6_route_is_prefix (&prefix, route);
1160: route = ospf6_route_next (route))
1161: {
1162: if (route->type != OSPF6_DEST_TYPE_NETWORK)
1163: continue;
1164: if (route->path.area_id != oa->area_id)
1165: continue;
1166: if (route->path.type != OSPF6_PATH_TYPE_INTRA)
1167: continue;
1168: if (route->path.origin.type != lsa->header->type ||
1169: route->path.origin.id != lsa->header->id ||
1170: route->path.origin.adv_router != lsa->header->adv_router)
1171: continue;
1172:
1173: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1174: {
1175: prefix2str (&route->prefix, buf, sizeof (buf));
1176: zlog_debug ("remove %s", buf);
1177: }
1178: ospf6_route_remove (route, oa->route_table);
1179: }
1180: if (route)
1181: ospf6_route_unlock (route);
1182: }
1183:
1184: if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1185: zlog_debug ("Trailing garbage ignored");
1186: }
1187:
1188: void
1189: ospf6_intra_route_calculation (struct ospf6_area *oa)
1190: {
1191: struct ospf6_route *route;
1192: u_int16_t type;
1193: struct ospf6_lsa *lsa;
1194: void (*hook_add) (struct ospf6_route *) = NULL;
1195: void (*hook_remove) (struct ospf6_route *) = NULL;
1196:
1197: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1198: zlog_debug ("Re-examin intra-routes for area %s", oa->name);
1199:
1200: hook_add = oa->route_table->hook_add;
1201: hook_remove = oa->route_table->hook_remove;
1202: oa->route_table->hook_add = NULL;
1203: oa->route_table->hook_remove = NULL;
1204:
1205: for (route = ospf6_route_head (oa->route_table); route;
1206: route = ospf6_route_next (route))
1207: route->flag = OSPF6_ROUTE_REMOVE;
1208:
1209: type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1210: for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
1211: lsa = ospf6_lsdb_type_next (type, lsa))
1212: ospf6_intra_prefix_lsa_add (lsa);
1213:
1214: oa->route_table->hook_add = hook_add;
1215: oa->route_table->hook_remove = hook_remove;
1216:
1217: for (route = ospf6_route_head (oa->route_table); route;
1218: route = ospf6_route_next (route))
1219: {
1220: if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
1221: CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
1222: {
1223: UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
1224: UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
1225: }
1226:
1227: if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
1228: ospf6_route_remove (route, oa->route_table);
1229: else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
1230: CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
1231: {
1232: if (hook_add)
1233: (*hook_add) (route);
1234: }
1235:
1236: route->flag = 0;
1237: }
1238:
1239: if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1240: zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
1241: }
1242:
1243: static void
1244: ospf6_brouter_debug_print (struct ospf6_route *brouter)
1245: {
1246: u_int32_t brouter_id;
1247: char brouter_name[16];
1248: char area_name[16];
1249: char destination[64];
1250: char installed[16], changed[16];
1251: struct timeval now, res;
1252: char id[16], adv_router[16];
1253: char capa[16], options[16];
1254:
1255: brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1256: inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1257: inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
1258: ospf6_linkstate_prefix2str (&brouter->prefix, destination,
1259: sizeof (destination));
1260:
1261: quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
1262: timersub (&now, &brouter->installed, &res);
1263: timerstring (&res, installed, sizeof (installed));
1264:
1265: quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
1266: timersub (&now, &brouter->changed, &res);
1267: timerstring (&res, changed, sizeof (changed));
1268:
1269: inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
1270: inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
1271: sizeof (adv_router));
1272:
1273: ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
1274: ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));
1275:
1276: zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
1277: zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
1278: brouter->prev, brouter, brouter->next, brouter->rnode);
1279: zlog_info (" type: %d prefix: %s installed: %s changed: %s",
1280: brouter->type, destination, installed, changed);
1281: zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock,
1282: (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
1283: (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
1284: (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
1285: (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
1286: zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
1287: OSPF6_PATH_TYPE_NAME (brouter->path.type),
1288: ospf6_lstype_name (brouter->path.origin.type),
1289: id, adv_router);
1290: zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1291: options, capa, brouter->path.metric_type,
1292: brouter->path.cost, brouter->path.cost_e2);
1293: }
1294:
1295: void
1296: ospf6_intra_brouter_calculation (struct ospf6_area *oa)
1297: {
1298: struct ospf6_route *brouter, *copy;
1299: void (*hook_add) (struct ospf6_route *) = NULL;
1300: void (*hook_remove) (struct ospf6_route *) = NULL;
1301: u_int32_t brouter_id;
1302: char brouter_name[16];
1303:
1304: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1305: zlog_info ("border-router calculation for area %s", oa->name);
1306:
1307: hook_add = oa->ospf6->brouter_table->hook_add;
1308: hook_remove = oa->ospf6->brouter_table->hook_remove;
1309: oa->ospf6->brouter_table->hook_add = NULL;
1310: oa->ospf6->brouter_table->hook_remove = NULL;
1311:
1312: /* withdraw the previous router entries for the area */
1313: for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1314: brouter = ospf6_route_next (brouter))
1315: {
1316: brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1317: inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1318: if (brouter->path.area_id != oa->area_id)
1319: continue;
1320: brouter->flag = OSPF6_ROUTE_REMOVE;
1321:
1322: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1323: IS_OSPF6_DEBUG_ROUTE (MEMORY))
1324: {
1325: zlog_info ("%p: mark as removing: area %s brouter %s",
1326: brouter, oa->name, brouter_name);
1327: ospf6_brouter_debug_print (brouter);
1328: }
1329: }
1330:
1331: for (brouter = ospf6_route_head (oa->spf_table); brouter;
1332: brouter = ospf6_route_next (brouter))
1333: {
1334: brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1335: inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1336:
1337: if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
1338: continue;
1339: if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
1340: continue;
1341: if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
1342: ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
1343: continue;
1344:
1345: copy = ospf6_route_copy (brouter);
1346: copy->type = OSPF6_DEST_TYPE_ROUTER;
1347: copy->path.area_id = oa->area_id;
1348: ospf6_route_add (copy, oa->ospf6->brouter_table);
1349:
1350: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1351: IS_OSPF6_DEBUG_ROUTE (MEMORY))
1352: {
1353: zlog_info ("%p: transfer: area %s brouter %s",
1354: brouter, oa->name, brouter_name);
1355: ospf6_brouter_debug_print (brouter);
1356: }
1357: }
1358:
1359: oa->ospf6->brouter_table->hook_add = hook_add;
1360: oa->ospf6->brouter_table->hook_remove = hook_remove;
1361:
1362: for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1363: brouter = ospf6_route_next (brouter))
1364: {
1365: brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1366: inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1367:
1368: if (brouter->path.area_id != oa->area_id)
1369: continue;
1370:
1371: if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
1372: continue;
1373:
1374: if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
1375: CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
1376: {
1377: UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
1378: UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
1379: }
1380:
1381: if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
1382: {
1383: if (IS_OSPF6_DEBUG_BROUTER ||
1384: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1385: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1386: zlog_info ("brouter %s disappears via area %s",
1387: brouter_name, oa->name);
1388: ospf6_route_remove (brouter, oa->ospf6->brouter_table);
1389: }
1390: else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
1391: CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
1392: {
1393: if (IS_OSPF6_DEBUG_BROUTER ||
1394: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1395: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1396: zlog_info ("brouter %s appears via area %s",
1397: brouter_name, oa->name);
1398:
1399: /* newly added */
1400: if (hook_add)
1401: (*hook_add) (brouter);
1402: }
1403: else
1404: {
1405: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1406: IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1407: zlog_info ("brouter %s still exists via area %s",
1408: brouter_name, oa->name);
1409: }
1410:
1411: brouter->flag = 0;
1412: }
1413:
1414: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1415: zlog_info ("border-router calculation for area %s: done", oa->name);
1416: }
1417:
1418: struct ospf6_lsa_handler router_handler =
1419: {
1420: OSPF6_LSTYPE_ROUTER,
1421: "Router",
1422: ospf6_router_lsa_show
1423: };
1424:
1425: struct ospf6_lsa_handler network_handler =
1426: {
1427: OSPF6_LSTYPE_NETWORK,
1428: "Network",
1429: ospf6_network_lsa_show
1430: };
1431:
1432: struct ospf6_lsa_handler link_handler =
1433: {
1434: OSPF6_LSTYPE_LINK,
1435: "Link",
1436: ospf6_link_lsa_show
1437: };
1438:
1439: struct ospf6_lsa_handler intra_prefix_handler =
1440: {
1441: OSPF6_LSTYPE_INTRA_PREFIX,
1442: "Intra-Prefix",
1443: ospf6_intra_prefix_lsa_show
1444: };
1445:
1446: void
1447: ospf6_intra_init (void)
1448: {
1449: ospf6_install_lsa_handler (&router_handler);
1450: ospf6_install_lsa_handler (&network_handler);
1451: ospf6_install_lsa_handler (&link_handler);
1452: ospf6_install_lsa_handler (&intra_prefix_handler);
1453: }
1454:
1455: DEFUN (debug_ospf6_brouter,
1456: debug_ospf6_brouter_cmd,
1457: "debug ospf6 border-routers",
1458: DEBUG_STR
1459: OSPF6_STR
1460: "Debug border router\n"
1461: )
1462: {
1463: OSPF6_DEBUG_BROUTER_ON ();
1464: return CMD_SUCCESS;
1465: }
1466:
1467: DEFUN (no_debug_ospf6_brouter,
1468: no_debug_ospf6_brouter_cmd,
1469: "no debug ospf6 border-routers",
1470: NO_STR
1471: DEBUG_STR
1472: OSPF6_STR
1473: "Debug border router\n"
1474: )
1475: {
1476: OSPF6_DEBUG_BROUTER_OFF ();
1477: return CMD_SUCCESS;
1478: }
1479:
1480: DEFUN (debug_ospf6_brouter_router,
1481: debug_ospf6_brouter_router_cmd,
1482: "debug ospf6 border-routers router-id A.B.C.D",
1483: DEBUG_STR
1484: OSPF6_STR
1485: "Debug border router\n"
1486: "Debug specific border router\n"
1487: "Specify border-router's router-id\n"
1488: )
1489: {
1490: u_int32_t router_id;
1491: inet_pton (AF_INET, argv[0], &router_id);
1492: OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
1493: return CMD_SUCCESS;
1494: }
1495:
1496: DEFUN (no_debug_ospf6_brouter_router,
1497: no_debug_ospf6_brouter_router_cmd,
1498: "no debug ospf6 border-routers router-id",
1499: NO_STR
1500: DEBUG_STR
1501: OSPF6_STR
1502: "Debug border router\n"
1503: "Debug specific border router\n"
1504: )
1505: {
1506: OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
1507: return CMD_SUCCESS;
1508: }
1509:
1510: DEFUN (debug_ospf6_brouter_area,
1511: debug_ospf6_brouter_area_cmd,
1512: "debug ospf6 border-routers area-id A.B.C.D",
1513: DEBUG_STR
1514: OSPF6_STR
1515: "Debug border router\n"
1516: "Debug border routers in specific Area\n"
1517: "Specify Area-ID\n"
1518: )
1519: {
1520: u_int32_t area_id;
1521: inet_pton (AF_INET, argv[0], &area_id);
1522: OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
1523: return CMD_SUCCESS;
1524: }
1525:
1526: DEFUN (no_debug_ospf6_brouter_area,
1527: no_debug_ospf6_brouter_area_cmd,
1528: "no debug ospf6 border-routers area-id",
1529: NO_STR
1530: DEBUG_STR
1531: OSPF6_STR
1532: "Debug border router\n"
1533: "Debug border routers in specific Area\n"
1534: )
1535: {
1536: OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
1537: return CMD_SUCCESS;
1538: }
1539:
1540: int
1541: config_write_ospf6_debug_brouter (struct vty *vty)
1542: {
1543: char buf[16];
1544: if (IS_OSPF6_DEBUG_BROUTER)
1545: vty_out (vty, "debug ospf6 border-routers%s", VNL);
1546: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
1547: {
1548: inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
1549: buf, sizeof (buf));
1550: vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
1551: }
1552: if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
1553: {
1554: inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
1555: buf, sizeof (buf));
1556: vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
1557: }
1558: return 0;
1559: }
1560:
1561: void
1562: install_element_ospf6_debug_brouter (void)
1563: {
1564: install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
1565: install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
1566: install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
1567: install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
1568: install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
1569: install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
1570: install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
1571: install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
1572: install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
1573: install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
1574: install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
1575: install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
1576: }
1577:
1578:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>