Annotation of embedaddon/quagga/ospf6d/ospf6_abr.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Area Border Router function.
3: * Copyright (C) 2004 Yasuhiro Ohara
4: *
5: * This file is part of GNU Zebra.
6: *
7: * GNU Zebra is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2, or (at your option) any
10: * later version.
11: *
12: * GNU Zebra is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public License
18: * along with GNU Zebra; see the file COPYING. If not, write to the
19: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20: * Boston, MA 02111-1307, USA.
21: */
22:
23: #include <zebra.h>
24:
25: #include "log.h"
26: #include "prefix.h"
27: #include "table.h"
28: #include "vty.h"
29: #include "linklist.h"
30: #include "command.h"
31: #include "thread.h"
32: #include "plist.h"
33: #include "filter.h"
34:
35: #include "ospf6_proto.h"
36: #include "ospf6_route.h"
37: #include "ospf6_lsa.h"
38: #include "ospf6_route.h"
39: #include "ospf6_lsdb.h"
40: #include "ospf6_message.h"
41:
42: #include "ospf6_top.h"
43: #include "ospf6_area.h"
44: #include "ospf6_interface.h"
45: #include "ospf6_neighbor.h"
46:
47: #include "ospf6_flood.h"
48: #include "ospf6_intra.h"
49: #include "ospf6_abr.h"
50: #include "ospf6d.h"
51:
52: unsigned char conf_debug_ospf6_abr;
53:
54: int
55: ospf6_is_router_abr (struct ospf6 *o)
56: {
57: struct listnode *node;
58: struct ospf6_area *oa;
59: int area_count = 0;
60:
61: for (ALL_LIST_ELEMENTS_RO (o->area_list, node, oa))
62: if (IS_AREA_ENABLED (oa))
63: area_count++;
64:
65: if (area_count > 1)
66: return 1;
67: return 0;
68: }
69:
70: void
71: ospf6_abr_enable_area (struct ospf6_area *area)
72: {
73: struct ospf6_area *oa;
74: struct ospf6_route *ro;
75: struct listnode *node, *nnode;
76:
77: for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
78: {
79: /* update B bit for each area */
80: OSPF6_ROUTER_LSA_SCHEDULE (oa);
81:
82: /* install other area's configured address range */
83: if (oa != area)
84: {
85: for (ro = ospf6_route_head (oa->range_table); ro;
86: ro = ospf6_route_next (ro))
87: {
88: if (CHECK_FLAG (ro->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
89: ospf6_abr_originate_summary_to_area (ro, area);
90: }
91: }
92: }
93:
94: /* install calculated routes to border routers */
95: for (ro = ospf6_route_head (area->ospf6->brouter_table); ro;
96: ro = ospf6_route_next (ro))
97: ospf6_abr_originate_summary_to_area (ro, area);
98:
99: /* install calculated routes to network (may be rejected by ranges) */
100: for (ro = ospf6_route_head (area->ospf6->route_table); ro;
101: ro = ospf6_route_next (ro))
102: ospf6_abr_originate_summary_to_area (ro, area);
103: }
104:
105: void
106: ospf6_abr_disable_area (struct ospf6_area *area)
107: {
108: struct ospf6_area *oa;
109: struct ospf6_route *ro;
110: struct ospf6_lsa *old;
111: struct listnode *node, *nnode;
112:
113: /* Withdraw all summary prefixes previously originated */
114: for (ro = ospf6_route_head (area->summary_prefix); ro;
115: ro = ospf6_route_next (ro))
116: {
117: old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
118: area->ospf6->router_id, area->lsdb);
119: if (old)
120: ospf6_lsa_purge (old);
121: ospf6_route_remove (ro, area->summary_prefix);
122: }
123:
124: /* Withdraw all summary router-routes previously originated */
125: for (ro = ospf6_route_head (area->summary_router); ro;
126: ro = ospf6_route_next (ro))
127: {
128: old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
129: area->ospf6->router_id, area->lsdb);
130: if (old)
131: ospf6_lsa_purge (old);
132: ospf6_route_remove (ro, area->summary_router);
133: }
134:
135: /* Schedule Router-LSA for each area (ABR status may change) */
136: for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
137: /* update B bit for each area */
138: OSPF6_ROUTER_LSA_SCHEDULE (oa);
139: }
140:
141: /* RFC 2328 12.4.3. Summary-LSAs */
142: void
143: ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
144: struct ospf6_area *area)
145: {
146: struct ospf6_lsa *lsa, *old = NULL;
147: struct ospf6_interface *oi;
148: struct ospf6_route *summary, *range = NULL;
149: struct ospf6_area *route_area;
150: char buffer[OSPF6_MAX_LSASIZE];
151: struct ospf6_lsa_header *lsa_header;
152: caddr_t p;
153: struct ospf6_inter_prefix_lsa *prefix_lsa;
154: struct ospf6_inter_router_lsa *router_lsa;
155: struct ospf6_route_table *summary_table = NULL;
156: u_int16_t type;
157: char buf[64];
158: int is_debug = 0;
159:
160: if (route->type == OSPF6_DEST_TYPE_ROUTER)
161: {
162: if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_ROUTER))
163: {
164: is_debug++;
165: inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
166: buf, sizeof (buf));
167: zlog_debug ("Originating summary in area %s for ASBR %s",
168: area->name, buf);
169: }
170: summary_table = area->summary_router;
171: }
172: else
173: {
174: if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_PREFIX))
175: {
176: is_debug++;
177: prefix2str (&route->prefix, buf, sizeof (buf));
178: zlog_debug ("Originating summary in area %s for %s",
179: area->name, buf);
180: }
181: summary_table = area->summary_prefix;
182: }
183:
184: summary = ospf6_route_lookup (&route->prefix, summary_table);
185: if (summary)
186: old = ospf6_lsdb_lookup (summary->path.origin.type,
187: summary->path.origin.id,
188: area->ospf6->router_id, area->lsdb);
189:
190: /* if this route has just removed, remove corresponding LSA */
191: if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
192: {
193: if (is_debug)
194: zlog_debug ("The route has just removed, purge previous LSA");
195: if (summary)
196: ospf6_route_remove (summary, summary_table);
197: if (old)
198: ospf6_lsa_purge (old);
199: return;
200: }
201:
202: /* Only destination type network, range or ASBR are considered */
203: if (route->type != OSPF6_DEST_TYPE_NETWORK &&
204: route->type != OSPF6_DEST_TYPE_RANGE &&
205: (route->type != OSPF6_DEST_TYPE_ROUTER ||
206: ! CHECK_FLAG (route->path.router_bits, OSPF6_ROUTER_BIT_E)))
207: {
208: if (is_debug)
209: zlog_debug ("Route type is none of network, range nor ASBR, withdraw");
210: if (summary)
211: ospf6_route_remove (summary, summary_table);
212: if (old)
213: ospf6_lsa_purge (old);
214: return;
215: }
216:
217: /* AS External routes are never considered */
218: if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
219: route->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
220: {
221: if (is_debug)
222: zlog_debug ("Path type is external, withdraw");
223: if (summary)
224: ospf6_route_remove (summary, summary_table);
225: if (old)
226: ospf6_lsa_purge (old);
227: return;
228: }
229:
230: /* do not generate if the path's area is the same as target area */
231: if (route->path.area_id == area->area_id)
232: {
233: if (is_debug)
234: zlog_debug ("The route is in the area itself, ignore");
235: if (summary)
236: ospf6_route_remove (summary, summary_table);
237: if (old)
238: ospf6_lsa_purge (old);
239: return;
240: }
241:
242: /* do not generate if the nexthops belongs to the target area */
243: oi = ospf6_interface_lookup_by_ifindex (route->nexthop[0].ifindex);
244: if (oi && oi->area && oi->area == area)
245: {
246: if (is_debug)
247: zlog_debug ("The route's nexthop is in the same area, ignore");
248: if (summary)
249: ospf6_route_remove (summary, summary_table);
250: if (old)
251: ospf6_lsa_purge (old);
252: return;
253: }
254:
255: /* do not generate if the route cost is greater or equal to LSInfinity */
256: if (route->path.cost >= LS_INFINITY)
257: {
258: if (is_debug)
259: zlog_debug ("The cost exceeds LSInfinity, withdraw");
260: if (summary)
261: ospf6_route_remove (summary, summary_table);
262: if (old)
263: ospf6_lsa_purge (old);
264: return;
265: }
266:
267: /* if this is a route to ASBR */
268: if (route->type == OSPF6_DEST_TYPE_ROUTER)
269: {
270: /* Only the prefered best path is considered */
271: if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_BEST))
272: {
273: if (is_debug)
274: zlog_debug ("This is the secondary path to the ASBR, ignore");
275: if (summary)
276: ospf6_route_remove (summary, summary_table);
277: if (old)
278: ospf6_lsa_purge (old);
279: return;
280: }
281:
282: /* Do not generate if the area is stub */
283: /* XXX */
284: }
285:
286: /* if this is an intra-area route, this may be suppressed by aggregation */
287: if (route->type == OSPF6_DEST_TYPE_NETWORK &&
288: route->path.type == OSPF6_PATH_TYPE_INTRA)
289: {
290: /* search for configured address range for the route's area */
291: route_area = ospf6_area_lookup (route->path.area_id, area->ospf6);
292: assert (route_area);
293: range = ospf6_route_lookup_bestmatch (&route->prefix,
294: route_area->range_table);
295:
296: /* ranges are ignored when originate backbone routes to transit area.
297: Otherwise, if ranges are configured, the route is suppressed. */
298: if (range && ! CHECK_FLAG (range->flag, OSPF6_ROUTE_REMOVE) &&
299: (route->path.area_id != BACKBONE_AREA_ID ||
300: ! IS_AREA_TRANSIT (area)))
301: {
302: if (is_debug)
303: {
304: prefix2str (&range->prefix, buf, sizeof (buf));
305: zlog_debug ("Suppressed by range %s of area %s",
306: buf, route_area->name);
307: }
308:
309: if (summary)
310: ospf6_route_remove (summary, summary_table);
311: if (old)
312: ospf6_lsa_purge (old);
313: return;
314: }
315: }
316:
317: /* If this is a configured address range */
318: if (route->type == OSPF6_DEST_TYPE_RANGE)
319: {
320: /* If DoNotAdvertise is set */
321: if (CHECK_FLAG (route->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
322: {
323: if (is_debug)
324: zlog_debug ("This is the range with DoNotAdvertise set. ignore");
325: if (summary)
326: ospf6_route_remove (summary, summary_table);
327: if (old)
328: ospf6_lsa_purge (old);
329: return;
330: }
331:
332: /* Whether the route have active longer prefix */
333: if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
334: {
335: if (is_debug)
336: zlog_debug ("The range is not active. withdraw");
337: if (summary)
338: ospf6_route_remove (summary, summary_table);
339: if (old)
340: ospf6_lsa_purge (old);
341: return;
342: }
343: }
344:
345: /* Check export list */
346: if (EXPORT_NAME (area))
347: {
348: if (EXPORT_LIST (area) == NULL)
349: EXPORT_LIST (area) =
350: access_list_lookup (AFI_IP6, EXPORT_NAME (area));
351:
352: if (EXPORT_LIST (area))
353: if (access_list_apply (EXPORT_LIST (area),
354: &route->prefix) == FILTER_DENY)
355: {
356: if (is_debug)
357: {
358: inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
359: buf, sizeof(buf));
360: zlog_debug ("prefix %s was denied by export list", buf);
361: }
362: return;
363: }
364: }
365:
366: /* Check filter-list */
367: if (PREFIX_NAME_OUT (area))
368: {
369: if (PREFIX_LIST_OUT (area) == NULL)
370: PREFIX_LIST_OUT (area) =
371: prefix_list_lookup(AFI_IP6, PREFIX_NAME_OUT (area));
372:
373: if (PREFIX_LIST_OUT (area))
374: if (prefix_list_apply (PREFIX_LIST_OUT (area),
375: &route->prefix) != PREFIX_PERMIT)
376: {
377: if (is_debug)
378: {
379: inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
380: buf, sizeof (buf));
381: zlog_debug ("prefix %s was denied by filter-list out", buf);
382: }
383: return;
384: }
385: }
386:
387: /* the route is going to be originated. store it in area's summary_table */
388: if (summary == NULL)
389: {
390: summary = ospf6_route_copy (route);
391: if (route->type == OSPF6_DEST_TYPE_NETWORK ||
392: route->type == OSPF6_DEST_TYPE_RANGE)
393: summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_PREFIX);
394: else
395: summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_ROUTER);
396: summary->path.origin.adv_router = area->ospf6->router_id;
397: summary->path.origin.id =
398: ospf6_new_ls_id (summary->path.origin.type,
399: summary->path.origin.adv_router, area->lsdb);
400: summary = ospf6_route_add (summary, summary_table);
401: }
402: else
403: {
404: summary->type = route->type;
405: quagga_gettime (QUAGGA_CLK_MONOTONIC, &summary->changed);
406: }
407:
408: summary->path.router_bits = route->path.router_bits;
409: summary->path.options[0] = route->path.options[0];
410: summary->path.options[1] = route->path.options[1];
411: summary->path.options[2] = route->path.options[2];
412: summary->path.prefix_options = route->path.prefix_options;
413: summary->path.area_id = area->area_id;
414: summary->path.type = OSPF6_PATH_TYPE_INTER;
415: summary->path.cost = route->path.cost;
416: summary->nexthop[0] = route->nexthop[0];
417:
418: /* prepare buffer */
419: memset (buffer, 0, sizeof (buffer));
420: lsa_header = (struct ospf6_lsa_header *) buffer;
421:
422: if (route->type == OSPF6_DEST_TYPE_ROUTER)
423: {
424: router_lsa = (struct ospf6_inter_router_lsa *)
425: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
426: p = (caddr_t) router_lsa + sizeof (struct ospf6_inter_router_lsa);
427:
428: /* Fill Inter-Area-Router-LSA */
429: router_lsa->options[0] = route->path.options[0];
430: router_lsa->options[1] = route->path.options[1];
431: router_lsa->options[2] = route->path.options[2];
432: OSPF6_ABR_SUMMARY_METRIC_SET (router_lsa, route->path.cost);
433: router_lsa->router_id = ADV_ROUTER_IN_PREFIX (&route->prefix);
434: type = htons (OSPF6_LSTYPE_INTER_ROUTER);
435: }
436: else
437: {
438: prefix_lsa = (struct ospf6_inter_prefix_lsa *)
439: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
440: p = (caddr_t) prefix_lsa + sizeof (struct ospf6_inter_prefix_lsa);
441:
442: /* Fill Inter-Area-Prefix-LSA */
443: OSPF6_ABR_SUMMARY_METRIC_SET (prefix_lsa, route->path.cost);
444: prefix_lsa->prefix.prefix_length = route->prefix.prefixlen;
445: prefix_lsa->prefix.prefix_options = route->path.prefix_options;
446:
447: /* set Prefix */
448: memcpy (p, &route->prefix.u.prefix6,
449: OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
450: ospf6_prefix_apply_mask (&prefix_lsa->prefix);
451: p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
452: type = htons (OSPF6_LSTYPE_INTER_PREFIX);
453: }
454:
455: /* Fill LSA Header */
456: lsa_header->age = 0;
457: lsa_header->type = type;
458: lsa_header->id = summary->path.origin.id;
459: lsa_header->adv_router = area->ospf6->router_id;
460: lsa_header->seqnum =
461: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
462: lsa_header->adv_router, area->lsdb);
463: lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
464:
465: /* LSA checksum */
466: ospf6_lsa_checksum (lsa_header);
467:
468: /* create LSA */
469: lsa = ospf6_lsa_create (lsa_header);
470:
471: /* Originate */
472: ospf6_lsa_originate_area (lsa, area);
473: }
474:
475: static void
476: ospf6_abr_range_update (struct ospf6_route *range)
477: {
478: u_int32_t cost = 0;
479: struct ospf6_route *ro;
480:
481: assert (range->type == OSPF6_DEST_TYPE_RANGE);
482:
483: /* update range's cost and active flag */
484: for (ro = ospf6_route_match_head (&range->prefix, ospf6->route_table);
485: ro; ro = ospf6_route_match_next (&range->prefix, ro))
486: {
487: if (ro->path.area_id == range->path.area_id &&
488: ! CHECK_FLAG (ro->flag, OSPF6_ROUTE_REMOVE))
489: cost = MAX (cost, ro->path.cost);
490: }
491:
492: if (range->path.cost != cost)
493: {
494: range->path.cost = cost;
495:
496: if (range->path.cost)
497: SET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
498: else
499: UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
500:
501: ospf6_abr_originate_summary (range);
502: }
503: }
504:
505: void
506: ospf6_abr_originate_summary (struct ospf6_route *route)
507: {
508: struct listnode *node, *nnode;
509: struct ospf6_area *oa;
510: struct ospf6_route *range = NULL;
511:
512: if (route->type == OSPF6_DEST_TYPE_NETWORK)
513: {
514: oa = ospf6_area_lookup (route->path.area_id, ospf6);
515: range = ospf6_route_lookup_bestmatch (&route->prefix, oa->range_table);
516: if (range)
517: ospf6_abr_range_update (range);
518: }
519:
520: for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
521: ospf6_abr_originate_summary_to_area (route, oa);
522: }
523:
524: /* RFC 2328 16.2. Calculating the inter-area routes */
525: void
526: ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
527: {
528: struct prefix prefix, abr_prefix;
529: struct ospf6_route_table *table = NULL;
530: struct ospf6_route *range, *route, *old = NULL;
531: struct ospf6_route *abr_entry;
532: u_char type = 0;
533: char options[3] = {0, 0, 0};
534: u_int8_t prefix_options = 0;
535: u_int32_t cost = 0;
536: u_char router_bits = 0;
537: int i;
538: char buf[64];
539: int is_debug = 0;
540:
541: memset (&prefix, 0, sizeof (prefix));
542:
543: if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
544: {
545: struct ospf6_inter_prefix_lsa *prefix_lsa;
546:
547: if (IS_OSPF6_DEBUG_EXAMIN (INTER_PREFIX))
548: {
549: is_debug++;
550: zlog_debug ("Examin %s in area %s", lsa->name, oa->name);
551: }
552:
553: prefix_lsa = (struct ospf6_inter_prefix_lsa *)
554: OSPF6_LSA_HEADER_END (lsa->header);
555: prefix.family = AF_INET6;
556: prefix.prefixlen = prefix_lsa->prefix.prefix_length;
557: ospf6_prefix_in6_addr (&prefix.u.prefix6, &prefix_lsa->prefix);
558: if (is_debug)
559: prefix2str (&prefix, buf, sizeof (buf));
560: table = oa->ospf6->route_table;
561: type = OSPF6_DEST_TYPE_NETWORK;
562: prefix_options = prefix_lsa->prefix.prefix_options;
563: cost = OSPF6_ABR_SUMMARY_METRIC (prefix_lsa);
564: }
565: else if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_ROUTER))
566: {
567: struct ospf6_inter_router_lsa *router_lsa;
568:
569: if (IS_OSPF6_DEBUG_EXAMIN (INTER_ROUTER))
570: {
571: is_debug++;
572: zlog_debug ("Examin %s in area %s", lsa->name, oa->name);
573: }
574:
575: router_lsa = (struct ospf6_inter_router_lsa *)
576: OSPF6_LSA_HEADER_END (lsa->header);
577: ospf6_linkstate_prefix (router_lsa->router_id, htonl (0), &prefix);
578: if (is_debug)
579: inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
580: table = oa->ospf6->brouter_table;
581: type = OSPF6_DEST_TYPE_ROUTER;
582: options[0] = router_lsa->options[0];
583: options[1] = router_lsa->options[1];
584: options[2] = router_lsa->options[2];
585: cost = OSPF6_ABR_SUMMARY_METRIC (router_lsa);
586: SET_FLAG (router_bits, OSPF6_ROUTER_BIT_E);
587: }
588: else
589: assert (0);
590:
591: /* Find existing route */
592: route = ospf6_route_lookup (&prefix, table);
593: if (route)
594: ospf6_route_lock (route);
595: while (route && ospf6_route_is_prefix (&prefix, route))
596: {
597: if (route->path.area_id == oa->area_id &&
598: route->path.origin.type == lsa->header->type &&
599: route->path.origin.id == lsa->header->id &&
600: route->path.origin.adv_router == lsa->header->adv_router &&
601: ! CHECK_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED))
602: old = route;
603: route = ospf6_route_next (route);
604: }
605:
606: /* (1) if cost == LSInfinity or if the LSA is MaxAge */
607: if (cost == LS_INFINITY)
608: {
609: if (is_debug)
610: zlog_debug ("cost is LS_INFINITY, ignore");
611: if (old)
612: ospf6_route_remove (old, table);
613: return;
614: }
615: if (OSPF6_LSA_IS_MAXAGE (lsa))
616: {
617: if (is_debug)
618: zlog_debug ("LSA is MaxAge, ignore");
619: if (old)
620: ospf6_route_remove (old, table);
621: return;
622: }
623:
624: /* (2) if the LSA is self-originated, ignore */
625: if (lsa->header->adv_router == oa->ospf6->router_id)
626: {
627: if (is_debug)
628: zlog_debug ("LSA is self-originated, ignore");
629: if (old)
630: ospf6_route_remove (old, table);
631: return;
632: }
633:
634: /* (3) if the prefix is equal to an active configured address range */
635: if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
636: {
637: range = ospf6_route_lookup (&prefix, oa->range_table);
638: if (range)
639: {
640: if (is_debug)
641: zlog_debug ("Prefix is equal to address range, ignore");
642: if (old)
643: ospf6_route_remove (old, table);
644: return;
645: }
646: }
647:
648: /* (4) if the routing table entry for the ABR does not exist */
649: ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &abr_prefix);
650: abr_entry = ospf6_route_lookup (&abr_prefix, oa->ospf6->brouter_table);
651: if (abr_entry == NULL || abr_entry->path.area_id != oa->area_id ||
652: CHECK_FLAG (abr_entry->flag, OSPF6_ROUTE_REMOVE) ||
653: ! CHECK_FLAG (abr_entry->path.router_bits, OSPF6_ROUTER_BIT_B))
654: {
655: if (is_debug)
656: zlog_debug ("ABR router entry does not exist, ignore");
657: if (old)
658: ospf6_route_remove (old, table);
659: return;
660: }
661:
662: /* Check import list */
663: if (IMPORT_NAME (oa))
664: {
665: if (IMPORT_LIST (oa) == NULL)
666: IMPORT_LIST (oa) = access_list_lookup (AFI_IP6, IMPORT_NAME (oa));
667:
668: if (IMPORT_LIST (oa))
669: if (access_list_apply (IMPORT_LIST (oa), &prefix) == FILTER_DENY)
670: {
671: if (is_debug)
672: zlog_debug ("Prefix was denied by import-list");
673: if (old)
674: ospf6_route_remove (old, table);
675: return;
676: }
677: }
678:
679: /* Check input prefix-list */
680: if (PREFIX_NAME_IN (oa))
681: {
682: if (PREFIX_LIST_IN (oa) == NULL)
683: PREFIX_LIST_IN (oa) = prefix_list_lookup (AFI_IP6, PREFIX_NAME_IN (oa));
684:
685: if (PREFIX_LIST_IN (oa))
686: if (prefix_list_apply (PREFIX_LIST_IN (oa), &prefix) != PREFIX_PERMIT)
687: {
688: if (is_debug)
689: zlog_debug ("Prefix was denied by prefix-list");
690: if (old)
691: ospf6_route_remove (old, table);
692: return;
693: }
694: }
695:
696: /* (5),(6),(7) the path preference is handled by the sorting
697: in the routing table. Always install the path by substituting
698: old route (if any). */
699: if (old)
700: route = ospf6_route_copy (old);
701: else
702: route = ospf6_route_create ();
703:
704: route->type = type;
705: route->prefix = prefix;
706: route->path.origin.type = lsa->header->type;
707: route->path.origin.id = lsa->header->id;
708: route->path.origin.adv_router = lsa->header->adv_router;
709: route->path.router_bits = router_bits;
710: route->path.options[0] = options[0];
711: route->path.options[1] = options[1];
712: route->path.options[2] = options[2];
713: route->path.prefix_options = prefix_options;
714: route->path.area_id = oa->area_id;
715: route->path.type = OSPF6_PATH_TYPE_INTER;
716: route->path.cost = abr_entry->path.cost + cost;
717: for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
718: route->nexthop[i] = abr_entry->nexthop[i];
719:
720: if (is_debug)
721: zlog_debug ("Install route: %s", buf);
722: ospf6_route_add (route, table);
723: }
724:
725: void
726: ospf6_abr_examin_brouter (u_int32_t router_id)
727: {
728: struct ospf6_lsa *lsa;
729: struct ospf6_area *oa;
730: struct listnode *node, *nnode;
731: u_int16_t type;
732:
733: for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
734: {
735: type = htons (OSPF6_LSTYPE_INTER_ROUTER);
736: for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa;
737: lsa = ospf6_lsdb_type_router_next (type, router_id, lsa))
738: ospf6_abr_examin_summary (lsa, oa);
739:
740: type = htons (OSPF6_LSTYPE_INTER_PREFIX);
741: for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa;
742: lsa = ospf6_lsdb_type_router_next (type, router_id, lsa))
743: ospf6_abr_examin_summary (lsa, oa);
744: }
745: }
746:
747: void
748: ospf6_abr_reimport (struct ospf6_area *oa)
749: {
750: struct ospf6_lsa *lsa;
751: u_int16_t type;
752:
753: type = htons (OSPF6_LSTYPE_INTER_ROUTER);
754: for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
755: lsa = ospf6_lsdb_type_next (type, lsa))
756: ospf6_abr_examin_summary (lsa, oa);
757:
758: type = htons (OSPF6_LSTYPE_INTER_PREFIX);
759: for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
760: lsa = ospf6_lsdb_type_next (type, lsa))
761: ospf6_abr_examin_summary (lsa, oa);
762: }
763:
764:
765:
766: /* Display functions */
767: static int
768: ospf6_inter_area_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
769: {
770: struct ospf6_inter_prefix_lsa *prefix_lsa;
771: struct in6_addr in6;
772: char buf[64];
773:
774: prefix_lsa = (struct ospf6_inter_prefix_lsa *)
775: OSPF6_LSA_HEADER_END (lsa->header);
776:
777: vty_out (vty, " Metric: %lu%s",
778: (u_long) OSPF6_ABR_SUMMARY_METRIC (prefix_lsa), VNL);
779:
780: ospf6_prefix_options_printbuf (prefix_lsa->prefix.prefix_options,
781: buf, sizeof (buf));
782: vty_out (vty, " Prefix Options: %s%s", buf, VNL);
783:
784: ospf6_prefix_in6_addr (&in6, &prefix_lsa->prefix);
785: inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
786: vty_out (vty, " Prefix: %s/%d%s", buf,
787: prefix_lsa->prefix.prefix_length, VNL);
788:
789: return 0;
790: }
791:
792: static int
793: ospf6_inter_area_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
794: {
795: struct ospf6_inter_router_lsa *router_lsa;
796: char buf[64];
797:
798: router_lsa = (struct ospf6_inter_router_lsa *)
799: OSPF6_LSA_HEADER_END (lsa->header);
800:
801: ospf6_options_printbuf (router_lsa->options, buf, sizeof (buf));
802: vty_out (vty, " Options: %s%s", buf, VNL);
803: vty_out (vty, " Metric: %lu%s",
804: (u_long) OSPF6_ABR_SUMMARY_METRIC (router_lsa), VNL);
805: inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
806: vty_out (vty, " Destination Router ID: %s%s", buf, VNL);
807:
808: return 0;
809: }
810:
811: /* Debug commands */
812: DEFUN (debug_ospf6_abr,
813: debug_ospf6_abr_cmd,
814: "debug ospf6 abr",
815: DEBUG_STR
816: OSPF6_STR
817: "Debug OSPFv3 ABR function\n"
818: )
819: {
820: OSPF6_DEBUG_ABR_ON ();
821: return CMD_SUCCESS;
822: }
823:
824: DEFUN (no_debug_ospf6_abr,
825: no_debug_ospf6_abr_cmd,
826: "no debug ospf6 abr",
827: NO_STR
828: DEBUG_STR
829: OSPF6_STR
830: "Debug OSPFv3 ABR function\n"
831: )
832: {
833: OSPF6_DEBUG_ABR_OFF ();
834: return CMD_SUCCESS;
835: }
836:
837: int
838: config_write_ospf6_debug_abr (struct vty *vty)
839: {
840: if (IS_OSPF6_DEBUG_ABR)
841: vty_out (vty, "debug ospf6 abr%s", VNL);
842: return 0;
843: }
844:
845: void
846: install_element_ospf6_debug_abr (void)
847: {
848: install_element (ENABLE_NODE, &debug_ospf6_abr_cmd);
849: install_element (ENABLE_NODE, &no_debug_ospf6_abr_cmd);
850: install_element (CONFIG_NODE, &debug_ospf6_abr_cmd);
851: install_element (CONFIG_NODE, &no_debug_ospf6_abr_cmd);
852: }
853:
854: struct ospf6_lsa_handler inter_prefix_handler =
855: {
856: OSPF6_LSTYPE_INTER_PREFIX,
857: "Inter-Prefix",
858: ospf6_inter_area_prefix_lsa_show
859: };
860:
861: struct ospf6_lsa_handler inter_router_handler =
862: {
863: OSPF6_LSTYPE_INTER_ROUTER,
864: "Inter-Router",
865: ospf6_inter_area_router_lsa_show
866: };
867:
868: void
869: ospf6_abr_init (void)
870: {
871: ospf6_install_lsa_handler (&inter_prefix_handler);
872: ospf6_install_lsa_handler (&inter_router_handler);
873: }
874:
875:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>