Annotation of embedaddon/quagga/ospf6d/ospf6_abr.c, revision 1.1.1.2
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 */
1.1.1.2 ! misho 256: if (route->path.cost >= OSPF_LS_INFINITY)
1.1 misho 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) &&
1.1.1.2 ! misho 299: (route->path.area_id != OSPF_AREA_BACKBONE ||
1.1 misho 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;
1.1.1.2 ! misho 540: struct ospf6_inter_prefix_lsa *prefix_lsa = NULL;
! 541: struct ospf6_inter_router_lsa *router_lsa = NULL;
1.1 misho 542:
543: memset (&prefix, 0, sizeof (prefix));
544:
545: if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
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: if (IS_OSPF6_DEBUG_EXAMIN (INTER_ROUTER))
568: {
569: is_debug++;
570: zlog_debug ("Examin %s in area %s", lsa->name, oa->name);
571: }
572:
573: router_lsa = (struct ospf6_inter_router_lsa *)
574: OSPF6_LSA_HEADER_END (lsa->header);
575: ospf6_linkstate_prefix (router_lsa->router_id, htonl (0), &prefix);
576: if (is_debug)
577: inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
578: table = oa->ospf6->brouter_table;
579: type = OSPF6_DEST_TYPE_ROUTER;
580: options[0] = router_lsa->options[0];
581: options[1] = router_lsa->options[1];
582: options[2] = router_lsa->options[2];
583: cost = OSPF6_ABR_SUMMARY_METRIC (router_lsa);
584: SET_FLAG (router_bits, OSPF6_ROUTER_BIT_E);
585: }
586: else
587: assert (0);
588:
589: /* Find existing route */
590: route = ospf6_route_lookup (&prefix, table);
591: if (route)
592: ospf6_route_lock (route);
593: while (route && ospf6_route_is_prefix (&prefix, route))
594: {
595: if (route->path.area_id == oa->area_id &&
596: route->path.origin.type == lsa->header->type &&
597: route->path.origin.id == lsa->header->id &&
598: route->path.origin.adv_router == lsa->header->adv_router &&
599: ! CHECK_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED))
600: old = route;
601: route = ospf6_route_next (route);
602: }
603:
604: /* (1) if cost == LSInfinity or if the LSA is MaxAge */
1.1.1.2 ! misho 605: if (cost == OSPF_LS_INFINITY)
1.1 misho 606: {
607: if (is_debug)
608: zlog_debug ("cost is LS_INFINITY, ignore");
609: if (old)
610: ospf6_route_remove (old, table);
611: return;
612: }
613: if (OSPF6_LSA_IS_MAXAGE (lsa))
614: {
615: if (is_debug)
616: zlog_debug ("LSA is MaxAge, ignore");
617: if (old)
618: ospf6_route_remove (old, table);
619: return;
620: }
621:
622: /* (2) if the LSA is self-originated, ignore */
623: if (lsa->header->adv_router == oa->ospf6->router_id)
624: {
625: if (is_debug)
626: zlog_debug ("LSA is self-originated, ignore");
627: if (old)
628: ospf6_route_remove (old, table);
629: return;
630: }
631:
632: /* (3) if the prefix is equal to an active configured address range */
1.1.1.2 ! misho 633: /* or if the NU bit is set in the prefix */
1.1 misho 634: if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
635: {
636: range = ospf6_route_lookup (&prefix, oa->range_table);
637: if (range)
638: {
639: if (is_debug)
640: zlog_debug ("Prefix is equal to address range, ignore");
641: if (old)
642: ospf6_route_remove (old, table);
643: return;
644: }
1.1.1.2 ! misho 645:
! 646: if (CHECK_FLAG (prefix_lsa->prefix.prefix_options,
! 647: OSPF6_PREFIX_OPTION_NU) ||
! 648: CHECK_FLAG (prefix_lsa->prefix.prefix_options,
! 649: OSPF6_PREFIX_OPTION_LA))
! 650: {
! 651: if (is_debug)
! 652: zlog_debug ("Prefix has NU/LA bit set, ignore");
! 653: if (old)
! 654: ospf6_route_remove (old, table);
! 655: return;
! 656: }
! 657: }
! 658:
! 659: if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_ROUTER))
! 660: {
! 661: /* To pass test suites */
! 662: if (! OSPF6_OPT_ISSET (router_lsa->options, OSPF6_OPT_R) ||
! 663: ! OSPF6_OPT_ISSET (router_lsa->options, OSPF6_OPT_V6))
! 664: {
! 665: if (is_debug)
! 666: zlog_debug ("Prefix has NU/LA bit set, ignore");
! 667: if (old)
! 668: ospf6_route_remove (old, table);
! 669: return;
! 670: }
1.1 misho 671: }
672:
673: /* (4) if the routing table entry for the ABR does not exist */
674: ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &abr_prefix);
675: abr_entry = ospf6_route_lookup (&abr_prefix, oa->ospf6->brouter_table);
676: if (abr_entry == NULL || abr_entry->path.area_id != oa->area_id ||
677: CHECK_FLAG (abr_entry->flag, OSPF6_ROUTE_REMOVE) ||
678: ! CHECK_FLAG (abr_entry->path.router_bits, OSPF6_ROUTER_BIT_B))
679: {
680: if (is_debug)
681: zlog_debug ("ABR router entry does not exist, ignore");
682: if (old)
683: ospf6_route_remove (old, table);
684: return;
685: }
686:
687: /* Check import list */
688: if (IMPORT_NAME (oa))
689: {
690: if (IMPORT_LIST (oa) == NULL)
691: IMPORT_LIST (oa) = access_list_lookup (AFI_IP6, IMPORT_NAME (oa));
692:
693: if (IMPORT_LIST (oa))
694: if (access_list_apply (IMPORT_LIST (oa), &prefix) == FILTER_DENY)
695: {
696: if (is_debug)
697: zlog_debug ("Prefix was denied by import-list");
698: if (old)
699: ospf6_route_remove (old, table);
700: return;
701: }
702: }
703:
704: /* Check input prefix-list */
705: if (PREFIX_NAME_IN (oa))
706: {
707: if (PREFIX_LIST_IN (oa) == NULL)
708: PREFIX_LIST_IN (oa) = prefix_list_lookup (AFI_IP6, PREFIX_NAME_IN (oa));
709:
710: if (PREFIX_LIST_IN (oa))
711: if (prefix_list_apply (PREFIX_LIST_IN (oa), &prefix) != PREFIX_PERMIT)
712: {
713: if (is_debug)
714: zlog_debug ("Prefix was denied by prefix-list");
715: if (old)
716: ospf6_route_remove (old, table);
717: return;
718: }
719: }
720:
721: /* (5),(6),(7) the path preference is handled by the sorting
722: in the routing table. Always install the path by substituting
723: old route (if any). */
724: if (old)
725: route = ospf6_route_copy (old);
726: else
727: route = ospf6_route_create ();
728:
729: route->type = type;
730: route->prefix = prefix;
731: route->path.origin.type = lsa->header->type;
732: route->path.origin.id = lsa->header->id;
733: route->path.origin.adv_router = lsa->header->adv_router;
734: route->path.router_bits = router_bits;
735: route->path.options[0] = options[0];
736: route->path.options[1] = options[1];
737: route->path.options[2] = options[2];
738: route->path.prefix_options = prefix_options;
739: route->path.area_id = oa->area_id;
740: route->path.type = OSPF6_PATH_TYPE_INTER;
741: route->path.cost = abr_entry->path.cost + cost;
742: for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
743: route->nexthop[i] = abr_entry->nexthop[i];
744:
745: if (is_debug)
746: zlog_debug ("Install route: %s", buf);
747: ospf6_route_add (route, table);
748: }
749:
750: void
751: ospf6_abr_examin_brouter (u_int32_t router_id)
752: {
753: struct ospf6_lsa *lsa;
754: struct ospf6_area *oa;
755: struct listnode *node, *nnode;
756: u_int16_t type;
757:
758: for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
759: {
760: type = htons (OSPF6_LSTYPE_INTER_ROUTER);
761: for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa;
762: lsa = ospf6_lsdb_type_router_next (type, router_id, lsa))
763: ospf6_abr_examin_summary (lsa, oa);
764:
765: type = htons (OSPF6_LSTYPE_INTER_PREFIX);
766: for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa;
767: lsa = ospf6_lsdb_type_router_next (type, router_id, lsa))
768: ospf6_abr_examin_summary (lsa, oa);
769: }
770: }
771:
772: void
773: ospf6_abr_reimport (struct ospf6_area *oa)
774: {
775: struct ospf6_lsa *lsa;
776: u_int16_t type;
777:
778: type = htons (OSPF6_LSTYPE_INTER_ROUTER);
779: for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
780: lsa = ospf6_lsdb_type_next (type, lsa))
781: ospf6_abr_examin_summary (lsa, oa);
782:
783: type = htons (OSPF6_LSTYPE_INTER_PREFIX);
784: for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
785: lsa = ospf6_lsdb_type_next (type, lsa))
786: ospf6_abr_examin_summary (lsa, oa);
787: }
788:
789:
1.1.1.2 ! misho 790:
1.1 misho 791: /* Display functions */
1.1.1.2 ! misho 792: static char *
! 793: ospf6_inter_area_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
! 794: int buflen, int pos)
! 795: {
! 796: struct ospf6_inter_prefix_lsa *prefix_lsa;
! 797: struct in6_addr in6;
! 798:
! 799: if (lsa != NULL)
! 800: {
! 801: prefix_lsa = (struct ospf6_inter_prefix_lsa *)
! 802: OSPF6_LSA_HEADER_END (lsa->header);
! 803:
! 804: ospf6_prefix_in6_addr (&in6, &prefix_lsa->prefix);
! 805: if (buf)
! 806: {
! 807: inet_ntop (AF_INET6, &in6, buf, buflen);
! 808: sprintf (&buf[strlen(buf)], "/%d", prefix_lsa->prefix.prefix_length);
! 809: }
! 810: }
! 811:
! 812: return (buf);
! 813: }
! 814:
1.1 misho 815: static int
816: ospf6_inter_area_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
817: {
818: struct ospf6_inter_prefix_lsa *prefix_lsa;
1.1.1.2 ! misho 819: char buf[INET6_ADDRSTRLEN];
1.1 misho 820:
821: prefix_lsa = (struct ospf6_inter_prefix_lsa *)
822: OSPF6_LSA_HEADER_END (lsa->header);
823:
824: vty_out (vty, " Metric: %lu%s",
825: (u_long) OSPF6_ABR_SUMMARY_METRIC (prefix_lsa), VNL);
826:
827: ospf6_prefix_options_printbuf (prefix_lsa->prefix.prefix_options,
828: buf, sizeof (buf));
829: vty_out (vty, " Prefix Options: %s%s", buf, VNL);
830:
1.1.1.2 ! misho 831: vty_out (vty, " Prefix: %s%s",
! 832: ospf6_inter_area_prefix_lsa_get_prefix_str (lsa, buf, sizeof(buf),
! 833: 0), VNL);
1.1 misho 834:
835: return 0;
836: }
837:
1.1.1.2 ! misho 838: static char *
! 839: ospf6_inter_area_router_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
! 840: int buflen, int pos)
! 841: {
! 842: struct ospf6_inter_router_lsa *router_lsa;
! 843:
! 844: if (lsa != NULL)
! 845: {
! 846: router_lsa = (struct ospf6_inter_router_lsa *)
! 847: OSPF6_LSA_HEADER_END (lsa->header);
! 848:
! 849:
! 850: if (buf)
! 851: inet_ntop (AF_INET, &router_lsa->router_id, buf, buflen);
! 852: }
! 853:
! 854: return (buf);
! 855: }
! 856:
1.1 misho 857: static int
858: ospf6_inter_area_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
859: {
860: struct ospf6_inter_router_lsa *router_lsa;
861: char buf[64];
862:
863: router_lsa = (struct ospf6_inter_router_lsa *)
864: OSPF6_LSA_HEADER_END (lsa->header);
865:
866: ospf6_options_printbuf (router_lsa->options, buf, sizeof (buf));
867: vty_out (vty, " Options: %s%s", buf, VNL);
868: vty_out (vty, " Metric: %lu%s",
869: (u_long) OSPF6_ABR_SUMMARY_METRIC (router_lsa), VNL);
1.1.1.2 ! misho 870:
1.1 misho 871: inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
872: vty_out (vty, " Destination Router ID: %s%s", buf, VNL);
873:
874: return 0;
875: }
876:
877: /* Debug commands */
878: DEFUN (debug_ospf6_abr,
879: debug_ospf6_abr_cmd,
880: "debug ospf6 abr",
881: DEBUG_STR
882: OSPF6_STR
883: "Debug OSPFv3 ABR function\n"
884: )
885: {
886: OSPF6_DEBUG_ABR_ON ();
887: return CMD_SUCCESS;
888: }
889:
890: DEFUN (no_debug_ospf6_abr,
891: no_debug_ospf6_abr_cmd,
892: "no debug ospf6 abr",
893: NO_STR
894: DEBUG_STR
895: OSPF6_STR
896: "Debug OSPFv3 ABR function\n"
897: )
898: {
899: OSPF6_DEBUG_ABR_OFF ();
900: return CMD_SUCCESS;
901: }
902:
903: int
904: config_write_ospf6_debug_abr (struct vty *vty)
905: {
906: if (IS_OSPF6_DEBUG_ABR)
907: vty_out (vty, "debug ospf6 abr%s", VNL);
908: return 0;
909: }
910:
911: void
912: install_element_ospf6_debug_abr (void)
913: {
914: install_element (ENABLE_NODE, &debug_ospf6_abr_cmd);
915: install_element (ENABLE_NODE, &no_debug_ospf6_abr_cmd);
916: install_element (CONFIG_NODE, &debug_ospf6_abr_cmd);
917: install_element (CONFIG_NODE, &no_debug_ospf6_abr_cmd);
918: }
919:
920: struct ospf6_lsa_handler inter_prefix_handler =
921: {
922: OSPF6_LSTYPE_INTER_PREFIX,
923: "Inter-Prefix",
1.1.1.2 ! misho 924: "IAP",
! 925: ospf6_inter_area_prefix_lsa_show,
! 926: ospf6_inter_area_prefix_lsa_get_prefix_str,
1.1 misho 927: };
928:
929: struct ospf6_lsa_handler inter_router_handler =
930: {
931: OSPF6_LSTYPE_INTER_ROUTER,
932: "Inter-Router",
1.1.1.2 ! misho 933: "IAR",
! 934: ospf6_inter_area_router_lsa_show,
! 935: ospf6_inter_area_router_lsa_get_prefix_str,
1.1 misho 936: };
937:
938: void
939: ospf6_abr_init (void)
940: {
941: ospf6_install_lsa_handler (&inter_prefix_handler);
942: ospf6_install_lsa_handler (&inter_router_handler);
943: }
944:
945:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>