Annotation of embedaddon/quagga/ospf6d/ospf6_asbr.c, revision 1.1.1.2
1.1 misho 1: /*
2: * Copyright (C) 2003 Yasuhiro Ohara
3: *
4: * This file is part of GNU Zebra.
5: *
6: * GNU Zebra is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2, or (at your option) any
9: * later version.
10: *
11: * GNU Zebra is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with GNU Zebra; see the file COPYING. If not, write to the
18: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19: * Boston, MA 02111-1307, USA.
20: */
21:
22: #include <zebra.h>
23:
24: #include "log.h"
25: #include "memory.h"
26: #include "prefix.h"
27: #include "command.h"
28: #include "vty.h"
29: #include "routemap.h"
30: #include "table.h"
31: #include "plist.h"
32: #include "thread.h"
33: #include "linklist.h"
34:
35: #include "ospf6_proto.h"
36: #include "ospf6_lsa.h"
37: #include "ospf6_lsdb.h"
38: #include "ospf6_route.h"
39: #include "ospf6_zebra.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: #include "ospf6_asbr.h"
47: #include "ospf6_intra.h"
48: #include "ospf6_flood.h"
49: #include "ospf6d.h"
50:
51: unsigned char conf_debug_ospf6_asbr = 0;
52:
53: #define ZROUTE_NAME(x) zebra_route_string(x)
54:
55: /* AS External LSA origination */
56: static void
57: ospf6_as_external_lsa_originate (struct ospf6_route *route)
58: {
59: char buffer[OSPF6_MAX_LSASIZE];
60: struct ospf6_lsa_header *lsa_header;
61: struct ospf6_lsa *old, *lsa;
62: struct ospf6_external_info *info = route->route_option;
63:
64: struct ospf6_as_external_lsa *as_external_lsa;
65: char buf[64];
66: caddr_t p;
67:
68: /* find previous LSA */
69: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
70: route->path.origin.id, ospf6->router_id,
71: ospf6->lsdb);
72:
73: if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))
74: {
75: prefix2str (&route->prefix, buf, sizeof (buf));
76: zlog_debug ("Originate AS-External-LSA for %s", buf);
77: }
78:
79: /* prepare buffer */
80: memset (buffer, 0, sizeof (buffer));
81: lsa_header = (struct ospf6_lsa_header *) buffer;
82: as_external_lsa = (struct ospf6_as_external_lsa *)
83: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
84: p = (caddr_t)
85: ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));
86:
87: /* Fill AS-External-LSA */
88: /* Metric type */
89: if (route->path.metric_type == 2)
90: SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
91: else
92: UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
93:
94: /* forwarding address */
95: if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
96: SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
97: else
98: UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
99:
100: /* external route tag */
101: UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
102:
103: /* Set metric */
104: OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
105:
106: /* prefixlen */
107: as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
108:
109: /* PrefixOptions */
110: as_external_lsa->prefix.prefix_options = route->path.prefix_options;
111:
112: /* don't use refer LS-type */
113: as_external_lsa->prefix.prefix_refer_lstype = htons (0);
114:
115: /* set Prefix */
116: memcpy (p, &route->prefix.u.prefix6,
117: OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
118: ospf6_prefix_apply_mask (&as_external_lsa->prefix);
119: p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
120:
121: /* Forwarding address */
122: if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
123: {
124: memcpy (p, &info->forwarding, sizeof (struct in6_addr));
125: p += sizeof (struct in6_addr);
126: }
127:
128: /* External Route Tag */
129: if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
130: {
131: /* xxx */
132: }
133:
134: /* Fill LSA Header */
135: lsa_header->age = 0;
136: lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
137: lsa_header->id = route->path.origin.id;
138: lsa_header->adv_router = ospf6->router_id;
139: lsa_header->seqnum =
140: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
141: lsa_header->adv_router, ospf6->lsdb);
142: lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
143:
144: /* LSA checksum */
145: ospf6_lsa_checksum (lsa_header);
146:
147: /* create LSA */
148: lsa = ospf6_lsa_create (lsa_header);
149:
150: /* Originate */
151: ospf6_lsa_originate_process (lsa, ospf6);
152: }
153:
154:
155: void
156: ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
157: {
158: struct ospf6_as_external_lsa *external;
159: struct prefix asbr_id;
160: struct ospf6_route *asbr_entry, *route;
161: char buf[64];
162: int i;
163:
164: external = (struct ospf6_as_external_lsa *)
165: OSPF6_LSA_HEADER_END (lsa->header);
166:
167: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
168: zlog_debug ("Calculate AS-External route for %s", lsa->name);
169:
170: if (lsa->header->adv_router == ospf6->router_id)
171: {
172: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
173: zlog_debug ("Ignore self-originated AS-External-LSA");
174: return;
175: }
176:
177: if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
178: {
179: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
180: zlog_debug ("Ignore LSA with LSInfinity Metric");
181: return;
182: }
183:
184: ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);
185: asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
186: if (asbr_entry == NULL ||
187: ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))
188: {
189: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
190: {
191: prefix2str (&asbr_id, buf, sizeof (buf));
192: zlog_debug ("ASBR entry not found: %s", buf);
193: }
194: return;
195: }
196:
197: route = ospf6_route_create ();
198: route->type = OSPF6_DEST_TYPE_NETWORK;
199: route->prefix.family = AF_INET6;
200: route->prefix.prefixlen = external->prefix.prefix_length;
201: ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
202:
203: route->path.area_id = asbr_entry->path.area_id;
204: route->path.origin.type = lsa->header->type;
205: route->path.origin.id = lsa->header->id;
206: route->path.origin.adv_router = lsa->header->adv_router;
207:
208: route->path.prefix_options = external->prefix.prefix_options;
209: if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
210: {
211: route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
212: route->path.metric_type = 2;
213: route->path.cost = asbr_entry->path.cost;
214: route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
215: }
216: else
217: {
218: route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
219: route->path.metric_type = 1;
220: route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
221: route->path.cost_e2 = 0;
222: }
223:
224: for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
225: ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
226:
227: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
228: {
229: prefix2str (&route->prefix, buf, sizeof (buf));
230: zlog_debug ("AS-External route add: %s", buf);
231: }
232:
233: ospf6_route_add (route, ospf6->route_table);
234: }
235:
236: void
237: ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
238: {
239: struct ospf6_as_external_lsa *external;
240: struct prefix prefix;
241: struct ospf6_route *route;
242: char buf[64];
243:
244: external = (struct ospf6_as_external_lsa *)
245: OSPF6_LSA_HEADER_END (lsa->header);
246:
247: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
248: zlog_debug ("Withdraw AS-External route for %s", lsa->name);
249:
250: if (lsa->header->adv_router == ospf6->router_id)
251: {
252: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
253: zlog_debug ("Ignore self-originated AS-External-LSA");
254: return;
255: }
256:
257: memset (&prefix, 0, sizeof (struct prefix));
258: prefix.family = AF_INET6;
259: prefix.prefixlen = external->prefix.prefix_length;
260: ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
261:
262: route = ospf6_route_lookup (&prefix, ospf6->route_table);
263: if (route == NULL)
264: {
265: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
266: {
267: prefix2str (&prefix, buf, sizeof (buf));
268: zlog_debug ("AS-External route %s not found", buf);
269: }
270: return;
271: }
272:
273: for (ospf6_route_lock (route);
274: route && ospf6_route_is_prefix (&prefix, route);
275: route = ospf6_route_next (route))
276: {
277: if (route->type != OSPF6_DEST_TYPE_NETWORK)
278: continue;
279: if (route->path.origin.type != lsa->header->type)
280: continue;
281: if (route->path.origin.id != lsa->header->id)
282: continue;
283: if (route->path.origin.adv_router != lsa->header->adv_router)
284: continue;
285:
286: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
287: {
288: prefix2str (&route->prefix, buf, sizeof (buf));
289: zlog_debug ("AS-External route remove: %s", buf);
290: }
291: ospf6_route_remove (route, ospf6->route_table);
292: }
293: }
294:
295: void
296: ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
297: {
298: struct ospf6_lsa *lsa;
299: u_int16_t type;
300: u_int32_t router;
301:
302: if (! CHECK_FLAG (asbr_entry->flag, OSPF6_ROUTE_BEST))
303: {
304: char buf[16];
305: inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (&asbr_entry->prefix),
306: buf, sizeof (buf));
307: zlog_info ("ignore non-best path: lsentry %s add", buf);
308: return;
309: }
310:
311: type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
312: router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
313: for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb); lsa;
314: lsa = ospf6_lsdb_type_router_next (type, router, lsa))
315: {
316: if (! OSPF6_LSA_IS_MAXAGE (lsa))
317: ospf6_asbr_lsa_add (lsa);
318: }
319: }
320:
321: void
322: ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
323: {
324: struct ospf6_lsa *lsa;
325: u_int16_t type;
326: u_int32_t router;
327:
328: type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
329: router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
330: for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
331: lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
332: ospf6_asbr_lsa_remove (lsa);
333: }
334:
335:
336:
337: /* redistribute function */
338:
339: static void
340: ospf6_asbr_routemap_set (int type, const char *mapname)
341: {
342: if (ospf6->rmap[type].name)
343: free (ospf6->rmap[type].name);
344: ospf6->rmap[type].name = strdup (mapname);
345: ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
346: }
347:
348: static void
349: ospf6_asbr_routemap_unset (int type)
350: {
351: if (ospf6->rmap[type].name)
352: free (ospf6->rmap[type].name);
353: ospf6->rmap[type].name = NULL;
354: ospf6->rmap[type].map = NULL;
355: }
356:
357: static void
358: ospf6_asbr_routemap_update (const char *mapname)
359: {
360: int type;
361:
362: if (ospf6 == NULL)
363: return;
364:
365: for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
366: {
367: if (ospf6->rmap[type].name)
368: ospf6->rmap[type].map =
369: route_map_lookup_by_name (ospf6->rmap[type].name);
370: else
371: ospf6->rmap[type].map = NULL;
372: }
373: }
374:
375: int
376: ospf6_asbr_is_asbr (struct ospf6 *o)
377: {
378: return o->external_table->count;
379: }
380:
381: static void
382: ospf6_asbr_redistribute_set (int type)
383: {
384: ospf6_zebra_redistribute (type);
385: }
386:
387: static void
388: ospf6_asbr_redistribute_unset (int type)
389: {
390: struct ospf6_route *route;
391: struct ospf6_external_info *info;
392:
393: ospf6_zebra_no_redistribute (type);
394:
395: for (route = ospf6_route_head (ospf6->external_table); route;
396: route = ospf6_route_next (route))
397: {
398: info = route->route_option;
399: if (info->type != type)
400: continue;
401:
402: ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
403: &route->prefix);
404: }
405: }
406:
407: void
408: ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
409: u_int nexthop_num, struct in6_addr *nexthop)
410: {
411: int ret;
412: struct ospf6_route troute;
413: struct ospf6_external_info tinfo;
414: struct ospf6_route *route, *match;
415: struct ospf6_external_info *info;
416: struct prefix prefix_id;
417: struct route_node *node;
418: char pbuf[64], ibuf[16];
419: struct listnode *lnode, *lnnode;
420: struct ospf6_area *oa;
421:
422: if (! ospf6_zebra_is_redistribute (type))
423: return;
424:
425: if (IS_OSPF6_DEBUG_ASBR)
426: {
427: prefix2str (prefix, pbuf, sizeof (pbuf));
428: zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
429: }
430:
431: /* if route-map was specified but not found, do not advertise */
432: if (ospf6->rmap[type].name)
433: {
434: if (ospf6->rmap[type].map == NULL)
435: ospf6_asbr_routemap_update (NULL);
436: if (ospf6->rmap[type].map == NULL)
437: {
438: zlog_warn ("route-map \"%s\" not found, suppress redistributing",
439: ospf6->rmap[type].name);
440: return;
441: }
442: }
443:
444: /* apply route-map */
445: if (ospf6->rmap[type].map)
446: {
447: memset (&troute, 0, sizeof (troute));
448: memset (&tinfo, 0, sizeof (tinfo));
449: troute.route_option = &tinfo;
1.1.1.2 ! misho 450: tinfo.ifindex = ifindex;
1.1 misho 451:
452: ret = route_map_apply (ospf6->rmap[type].map, prefix,
453: RMAP_OSPF6, &troute);
454: if (ret == RMAP_DENYMATCH)
455: {
456: if (IS_OSPF6_DEBUG_ASBR)
457: zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
458: return;
459: }
460: }
461:
462: match = ospf6_route_lookup (prefix, ospf6->external_table);
463: if (match)
464: {
465: info = match->route_option;
466:
467: /* copy result of route-map */
468: if (ospf6->rmap[type].map)
469: {
470: if (troute.path.metric_type)
471: match->path.metric_type = troute.path.metric_type;
472: if (troute.path.cost)
473: match->path.cost = troute.path.cost;
474: if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
475: memcpy (&info->forwarding, &tinfo.forwarding,
476: sizeof (struct in6_addr));
477: }
478:
479: info->type = type;
480: match->nexthop[0].ifindex = ifindex;
481: if (nexthop_num && nexthop)
482: memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
483:
484: /* create/update binding in external_id_table */
485: prefix_id.family = AF_INET;
486: prefix_id.prefixlen = 32;
487: prefix_id.u.prefix4.s_addr = htonl (info->id);
488: node = route_node_get (ospf6->external_id_table, &prefix_id);
489: node->info = match;
490:
491: if (IS_OSPF6_DEBUG_ASBR)
492: {
493: inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
494: zlog_debug ("Advertise as AS-External Id:%s", ibuf);
495: }
496:
497: match->path.origin.id = htonl (info->id);
498: ospf6_as_external_lsa_originate (match);
499: return;
500: }
501:
502: /* create new entry */
503: route = ospf6_route_create ();
504: route->type = OSPF6_DEST_TYPE_NETWORK;
505: memcpy (&route->prefix, prefix, sizeof (struct prefix));
506:
507: info = (struct ospf6_external_info *)
508: XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
509: route->route_option = info;
510: info->id = ospf6->external_id++;
511:
512: /* copy result of route-map */
513: if (ospf6->rmap[type].map)
514: {
515: if (troute.path.metric_type)
516: route->path.metric_type = troute.path.metric_type;
517: if (troute.path.cost)
518: route->path.cost = troute.path.cost;
519: if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
520: memcpy (&info->forwarding, &tinfo.forwarding,
521: sizeof (struct in6_addr));
522: }
523:
524: info->type = type;
525: route->nexthop[0].ifindex = ifindex;
526: if (nexthop_num && nexthop)
527: memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
528:
529: /* create/update binding in external_id_table */
530: prefix_id.family = AF_INET;
531: prefix_id.prefixlen = 32;
532: prefix_id.u.prefix4.s_addr = htonl (info->id);
533: node = route_node_get (ospf6->external_id_table, &prefix_id);
534: node->info = route;
535:
536: route = ospf6_route_add (route, ospf6->external_table);
537: route->route_option = info;
538:
539: if (IS_OSPF6_DEBUG_ASBR)
540: {
541: inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
542: zlog_debug ("Advertise as AS-External Id:%s", ibuf);
543: }
544:
545: route->path.origin.id = htonl (info->id);
546: ospf6_as_external_lsa_originate (route);
547:
548: /* Router-Bit (ASBR Flag) may have to be updated */
549: for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
550: OSPF6_ROUTER_LSA_SCHEDULE (oa);
551: }
552:
553: void
554: ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
555: {
556: struct ospf6_route *match;
557: struct ospf6_external_info *info = NULL;
558: struct route_node *node;
559: struct ospf6_lsa *lsa;
560: struct prefix prefix_id;
561: char pbuf[64], ibuf[16];
562: struct listnode *lnode, *lnnode;
563: struct ospf6_area *oa;
564:
565: match = ospf6_route_lookup (prefix, ospf6->external_table);
566: if (match == NULL)
567: {
568: if (IS_OSPF6_DEBUG_ASBR)
569: {
570: prefix2str (prefix, pbuf, sizeof (pbuf));
571: zlog_debug ("No such route %s to withdraw", pbuf);
572: }
573: return;
574: }
575:
576: info = match->route_option;
577: assert (info);
578:
579: if (info->type != type)
580: {
581: if (IS_OSPF6_DEBUG_ASBR)
582: {
583: prefix2str (prefix, pbuf, sizeof (pbuf));
584: zlog_debug ("Original protocol mismatch: %s", pbuf);
585: }
586: return;
587: }
588:
589: if (IS_OSPF6_DEBUG_ASBR)
590: {
591: prefix2str (prefix, pbuf, sizeof (pbuf));
592: inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
593: zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
594: }
595:
596: lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
597: htonl (info->id), ospf6->router_id, ospf6->lsdb);
598: if (lsa)
599: ospf6_lsa_purge (lsa);
600:
601: /* remove binding in external_id_table */
602: prefix_id.family = AF_INET;
603: prefix_id.prefixlen = 32;
604: prefix_id.u.prefix4.s_addr = htonl (info->id);
605: node = route_node_lookup (ospf6->external_id_table, &prefix_id);
606: assert (node);
607: node->info = NULL;
608: route_unlock_node (node);
609:
610: ospf6_route_remove (match, ospf6->external_table);
611: XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
612:
613: /* Router-Bit (ASBR Flag) may have to be updated */
614: for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
615: OSPF6_ROUTER_LSA_SCHEDULE (oa);
616: }
617:
618: DEFUN (ospf6_redistribute,
619: ospf6_redistribute_cmd,
1.1.1.2 ! misho 620: "redistribute " QUAGGA_REDIST_STR_OSPF6D,
1.1 misho 621: "Redistribute\n"
1.1.1.2 ! misho 622: QUAGGA_REDIST_HELP_STR_OSPF6D
1.1 misho 623: )
624: {
1.1.1.2 ! misho 625: int type;
1.1 misho 626:
1.1.1.2 ! misho 627: type = proto_redistnum(AFI_IP6, argv[0]);
! 628: if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
! 629: return CMD_WARNING;
1.1 misho 630:
631: ospf6_asbr_redistribute_unset (type);
632: ospf6_asbr_routemap_unset (type);
633: ospf6_asbr_redistribute_set (type);
634: return CMD_SUCCESS;
635: }
636:
637: DEFUN (ospf6_redistribute_routemap,
638: ospf6_redistribute_routemap_cmd,
1.1.1.2 ! misho 639: "redistribute " QUAGGA_REDIST_STR_OSPF6D " route-map WORD",
1.1 misho 640: "Redistribute\n"
1.1.1.2 ! misho 641: QUAGGA_REDIST_HELP_STR_OSPF6D
1.1 misho 642: "Route map reference\n"
643: "Route map name\n"
644: )
645: {
1.1.1.2 ! misho 646: int type;
1.1 misho 647:
1.1.1.2 ! misho 648: type = proto_redistnum(AFI_IP6, argv[0]);
! 649: if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
! 650: return CMD_WARNING;
1.1 misho 651:
652: ospf6_asbr_redistribute_unset (type);
653: ospf6_asbr_routemap_set (type, argv[1]);
654: ospf6_asbr_redistribute_set (type);
655: return CMD_SUCCESS;
656: }
657:
658: DEFUN (no_ospf6_redistribute,
659: no_ospf6_redistribute_cmd,
1.1.1.2 ! misho 660: "no redistribute " QUAGGA_REDIST_STR_OSPF6D,
1.1 misho 661: NO_STR
662: "Redistribute\n"
1.1.1.2 ! misho 663: QUAGGA_REDIST_HELP_STR_OSPF6D
1.1 misho 664: )
665: {
1.1.1.2 ! misho 666: int type;
1.1 misho 667:
1.1.1.2 ! misho 668: type = proto_redistnum(AFI_IP6, argv[0]);
! 669: if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
! 670: return CMD_WARNING;
1.1 misho 671:
672: ospf6_asbr_redistribute_unset (type);
673: ospf6_asbr_routemap_unset (type);
674:
675: return CMD_SUCCESS;
676: }
677:
678: int
679: ospf6_redistribute_config_write (struct vty *vty)
680: {
681: int type;
682:
683: for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
684: {
685: if (type == ZEBRA_ROUTE_OSPF6)
686: continue;
687: if (! ospf6_zebra_is_redistribute (type))
688: continue;
689:
690: if (ospf6->rmap[type].name)
691: vty_out (vty, " redistribute %s route-map %s%s",
692: ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
693: else
694: vty_out (vty, " redistribute %s%s",
695: ZROUTE_NAME (type), VNL);
696: }
697:
698: return 0;
699: }
700:
701: static void
702: ospf6_redistribute_show_config (struct vty *vty)
703: {
704: int type;
705: int nroute[ZEBRA_ROUTE_MAX];
706: int total;
707: struct ospf6_route *route;
708: struct ospf6_external_info *info;
709:
710: total = 0;
711: for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
712: nroute[type] = 0;
713: for (route = ospf6_route_head (ospf6->external_table); route;
714: route = ospf6_route_next (route))
715: {
716: info = route->route_option;
717: nroute[info->type]++;
718: total++;
719: }
720:
721: vty_out (vty, "Redistributing External Routes from:%s", VNL);
722: for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
723: {
724: if (type == ZEBRA_ROUTE_OSPF6)
725: continue;
726: if (! ospf6_zebra_is_redistribute (type))
727: continue;
728:
729: if (ospf6->rmap[type].name)
730: vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
731: ZROUTE_NAME (type), ospf6->rmap[type].name,
732: (ospf6->rmap[type].map ? "" : " (not found !)"),
733: VNL);
734: else
735: vty_out (vty, " %d: %s%s", nroute[type],
736: ZROUTE_NAME (type), VNL);
737: }
738: vty_out (vty, "Total %d routes%s", total, VNL);
739: }
740:
741:
742:
743: /* Routemap Functions */
744: static route_map_result_t
745: ospf6_routemap_rule_match_address_prefixlist (void *rule,
746: struct prefix *prefix,
747: route_map_object_t type,
748: void *object)
749: {
750: struct prefix_list *plist;
751:
752: if (type != RMAP_OSPF6)
753: return RMAP_NOMATCH;
754:
755: plist = prefix_list_lookup (AFI_IP6, (char *) rule);
756: if (plist == NULL)
757: return RMAP_NOMATCH;
758:
759: return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
760: RMAP_NOMATCH : RMAP_MATCH);
761: }
762:
763: static void *
764: ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
765: {
766: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
767: }
768:
769: static void
770: ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
771: {
772: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
773: }
774:
775: struct route_map_rule_cmd
776: ospf6_routemap_rule_match_address_prefixlist_cmd =
777: {
778: "ipv6 address prefix-list",
779: ospf6_routemap_rule_match_address_prefixlist,
780: ospf6_routemap_rule_match_address_prefixlist_compile,
781: ospf6_routemap_rule_match_address_prefixlist_free,
782: };
783:
1.1.1.2 ! misho 784: /* `match interface IFNAME' */
! 785: /* Match function should return 1 if match is success else return
! 786: zero. */
! 787: static route_map_result_t
! 788: ospf6_routemap_rule_match_interface (void *rule, struct prefix *prefix,
! 789: route_map_object_t type, void *object)
! 790: {
! 791: struct interface *ifp;
! 792: struct ospf6_external_info *ei;
! 793:
! 794: if (type == RMAP_OSPF6)
! 795: {
! 796: ei = ((struct ospf6_route *) object)->route_option;
! 797: ifp = if_lookup_by_name ((char *)rule);
! 798:
! 799: if (ifp != NULL
! 800: && ei->ifindex == ifp->ifindex)
! 801: return RMAP_MATCH;
! 802: }
! 803:
! 804: return RMAP_NOMATCH;
! 805: }
! 806:
! 807: /* Route map `interface' match statement. `arg' should be
! 808: interface name. */
! 809: static void *
! 810: ospf6_routemap_rule_match_interface_compile (const char *arg)
! 811: {
! 812: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
! 813: }
! 814:
! 815: /* Free route map's compiled `interface' value. */
! 816: static void
! 817: ospf6_routemap_rule_match_interface_free (void *rule)
! 818: {
! 819: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
! 820: }
! 821:
! 822: /* Route map commands for interface matching. */
! 823: struct route_map_rule_cmd
! 824: ospf6_routemap_rule_match_interface_cmd =
! 825: {
! 826: "interface",
! 827: ospf6_routemap_rule_match_interface,
! 828: ospf6_routemap_rule_match_interface_compile,
! 829: ospf6_routemap_rule_match_interface_free
! 830: };
! 831:
1.1 misho 832: static route_map_result_t
833: ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
834: route_map_object_t type, void *object)
835: {
836: char *metric_type = rule;
837: struct ospf6_route *route = object;
838:
839: if (type != RMAP_OSPF6)
840: return RMAP_OKAY;
841:
842: if (strcmp (metric_type, "type-2") == 0)
843: route->path.metric_type = 2;
844: else
845: route->path.metric_type = 1;
846:
847: return RMAP_OKAY;
848: }
849:
850: static void *
851: ospf6_routemap_rule_set_metric_type_compile (const char *arg)
852: {
853: if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
854: return NULL;
855: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
856: }
857:
858: static void
859: ospf6_routemap_rule_set_metric_type_free (void *rule)
860: {
861: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
862: }
863:
864: struct route_map_rule_cmd
865: ospf6_routemap_rule_set_metric_type_cmd =
866: {
867: "metric-type",
868: ospf6_routemap_rule_set_metric_type,
869: ospf6_routemap_rule_set_metric_type_compile,
870: ospf6_routemap_rule_set_metric_type_free,
871: };
872:
873: static route_map_result_t
874: ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
875: route_map_object_t type, void *object)
876: {
877: char *metric = rule;
878: struct ospf6_route *route = object;
879:
880: if (type != RMAP_OSPF6)
881: return RMAP_OKAY;
882:
883: route->path.cost = atoi (metric);
884: return RMAP_OKAY;
885: }
886:
887: static void *
888: ospf6_routemap_rule_set_metric_compile (const char *arg)
889: {
890: u_int32_t metric;
891: char *endp;
892: metric = strtoul (arg, &endp, 0);
893: if (metric > LS_INFINITY || *endp != '\0')
894: return NULL;
895: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
896: }
897:
898: static void
899: ospf6_routemap_rule_set_metric_free (void *rule)
900: {
901: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
902: }
903:
904: struct route_map_rule_cmd
905: ospf6_routemap_rule_set_metric_cmd =
906: {
907: "metric",
908: ospf6_routemap_rule_set_metric,
909: ospf6_routemap_rule_set_metric_compile,
910: ospf6_routemap_rule_set_metric_free,
911: };
912:
913: static route_map_result_t
914: ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
915: route_map_object_t type, void *object)
916: {
917: char *forwarding = rule;
918: struct ospf6_route *route = object;
919: struct ospf6_external_info *info = route->route_option;
920:
921: if (type != RMAP_OSPF6)
922: return RMAP_OKAY;
923:
924: if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
925: {
926: memset (&info->forwarding, 0, sizeof (struct in6_addr));
927: return RMAP_ERROR;
928: }
929:
930: return RMAP_OKAY;
931: }
932:
933: static void *
934: ospf6_routemap_rule_set_forwarding_compile (const char *arg)
935: {
936: struct in6_addr a;
937: if (inet_pton (AF_INET6, arg, &a) != 1)
938: return NULL;
939: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
940: }
941:
942: static void
943: ospf6_routemap_rule_set_forwarding_free (void *rule)
944: {
945: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
946: }
947:
948: struct route_map_rule_cmd
949: ospf6_routemap_rule_set_forwarding_cmd =
950: {
951: "forwarding-address",
952: ospf6_routemap_rule_set_forwarding,
953: ospf6_routemap_rule_set_forwarding_compile,
954: ospf6_routemap_rule_set_forwarding_free,
955: };
956:
957: static int
958: route_map_command_status (struct vty *vty, int ret)
959: {
960: if (! ret)
961: return CMD_SUCCESS;
962:
963: switch (ret)
964: {
965: case RMAP_RULE_MISSING:
966: vty_out (vty, "Can't find rule.%s", VNL);
967: break;
968: case RMAP_COMPILE_ERROR:
969: vty_out (vty, "Argument is malformed.%s", VNL);
970: break;
971: default:
972: vty_out (vty, "route-map add set failed.%s", VNL);
973: break;
974: }
975: return CMD_WARNING;
976: }
977:
978: /* add "match address" */
979: DEFUN (ospf6_routemap_match_address_prefixlist,
980: ospf6_routemap_match_address_prefixlist_cmd,
981: "match ipv6 address prefix-list WORD",
982: "Match values\n"
983: IPV6_STR
984: "Match address of route\n"
985: "Match entries of prefix-lists\n"
986: "IPv6 prefix-list name\n")
987: {
988: int ret = route_map_add_match ((struct route_map_index *) vty->index,
989: "ipv6 address prefix-list", argv[0]);
990: return route_map_command_status (vty, ret);
991: }
992:
993: /* delete "match address" */
994: DEFUN (ospf6_routemap_no_match_address_prefixlist,
995: ospf6_routemap_no_match_address_prefixlist_cmd,
996: "no match ipv6 address prefix-list WORD",
997: NO_STR
998: "Match values\n"
999: IPV6_STR
1000: "Match address of route\n"
1001: "Match entries of prefix-lists\n"
1002: "IPv6 prefix-list name\n")
1003: {
1004: int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1005: "ipv6 address prefix-list", argv[0]);
1006: return route_map_command_status (vty, ret);
1007: }
1008:
1.1.1.2 ! misho 1009: /* "match interface" */
! 1010: DEFUN (ospf6_routemap_match_interface,
! 1011: ospf6_routemap_match_interface_cmd,
! 1012: "match interface WORD",
! 1013: MATCH_STR
! 1014: "Match first hop interface of route\n"
! 1015: "Interface name\n")
! 1016: {
! 1017: return route_map_add_match ((struct route_map_index *) vty->index,
! 1018: "interface", argv[0]);
! 1019: }
! 1020:
! 1021: /* "no match interface WORD" */
! 1022: DEFUN (ospf6_routemap_no_match_interface,
! 1023: ospf6_routemap_no_match_interface_cmd,
! 1024: "no match interface",
! 1025: MATCH_STR
! 1026: NO_STR
! 1027: "Match first hop interface of route\n")
! 1028: {
! 1029: int ret = route_map_delete_match ((struct route_map_index *) vty->index,
! 1030: "interface", (argc == 0) ? NULL : argv[0]);
! 1031: return route_map_command_status (vty, ret);
! 1032: }
! 1033:
! 1034: ALIAS (ospf6_routemap_no_match_interface,
! 1035: ospf6_routemap_no_match_interface_val_cmd,
! 1036: "no match interface WORD",
! 1037: MATCH_STR
! 1038: NO_STR
! 1039: "Match first hop interface of route\n"
! 1040: "Interface name\n")
! 1041:
1.1 misho 1042: /* add "set metric-type" */
1043: DEFUN (ospf6_routemap_set_metric_type,
1044: ospf6_routemap_set_metric_type_cmd,
1045: "set metric-type (type-1|type-2)",
1046: "Set value\n"
1047: "Type of metric\n"
1048: "OSPF6 external type 1 metric\n"
1049: "OSPF6 external type 2 metric\n")
1050: {
1051: int ret = route_map_add_set ((struct route_map_index *) vty->index,
1052: "metric-type", argv[0]);
1053: return route_map_command_status (vty, ret);
1054: }
1055:
1056: /* delete "set metric-type" */
1057: DEFUN (ospf6_routemap_no_set_metric_type,
1058: ospf6_routemap_no_set_metric_type_cmd,
1059: "no set metric-type (type-1|type-2)",
1060: NO_STR
1061: "Set value\n"
1062: "Type of metric\n"
1063: "OSPF6 external type 1 metric\n"
1064: "OSPF6 external type 2 metric\n")
1065: {
1066: int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1067: "metric-type", argv[0]);
1068: return route_map_command_status (vty, ret);
1069: }
1070:
1071: /* add "set metric" */
1072: DEFUN (set_metric,
1073: set_metric_cmd,
1074: "set metric <0-4294967295>",
1075: "Set value\n"
1076: "Metric value\n"
1077: "Metric value\n")
1078: {
1079: int ret = route_map_add_set ((struct route_map_index *) vty->index,
1080: "metric", argv[0]);
1081: return route_map_command_status (vty, ret);
1082: }
1083:
1084: /* delete "set metric" */
1085: DEFUN (no_set_metric,
1086: no_set_metric_cmd,
1087: "no set metric <0-4294967295>",
1088: NO_STR
1089: "Set value\n"
1090: "Metric\n"
1091: "METRIC value\n")
1092: {
1093: int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1094: "metric", argv[0]);
1095: return route_map_command_status (vty, ret);
1096: }
1097:
1098: /* add "set forwarding-address" */
1099: DEFUN (ospf6_routemap_set_forwarding,
1100: ospf6_routemap_set_forwarding_cmd,
1101: "set forwarding-address X:X::X:X",
1102: "Set value\n"
1103: "Forwarding Address\n"
1104: "IPv6 Address\n")
1105: {
1106: int ret = route_map_add_set ((struct route_map_index *) vty->index,
1107: "forwarding-address", argv[0]);
1108: return route_map_command_status (vty, ret);
1109: }
1110:
1111: /* delete "set forwarding-address" */
1112: DEFUN (ospf6_routemap_no_set_forwarding,
1113: ospf6_routemap_no_set_forwarding_cmd,
1114: "no set forwarding-address X:X::X:X",
1115: NO_STR
1116: "Set value\n"
1117: "Forwarding Address\n"
1118: "IPv6 Address\n")
1119: {
1120: int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1121: "forwarding-address", argv[0]);
1122: return route_map_command_status (vty, ret);
1123: }
1124:
1125: static void
1126: ospf6_routemap_init (void)
1127: {
1128: route_map_init ();
1129: route_map_init_vty ();
1130: route_map_add_hook (ospf6_asbr_routemap_update);
1131: route_map_delete_hook (ospf6_asbr_routemap_update);
1132:
1133: route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
1.1.1.2 ! misho 1134: route_map_install_match (&ospf6_routemap_rule_match_interface_cmd);
! 1135:
1.1 misho 1136: route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
1137: route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
1138: route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
1139:
1140: /* Match address prefix-list */
1141: install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
1142: install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
1143:
1.1.1.2 ! misho 1144: /* Match interface */
! 1145: install_element (RMAP_NODE, &ospf6_routemap_match_interface_cmd);
! 1146: install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_cmd);
! 1147: install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_val_cmd);
! 1148:
1.1 misho 1149: /* ASE Metric Type (e.g. Type-1/Type-2) */
1150: install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
1151: install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
1152:
1153: /* ASE Metric */
1154: install_element (RMAP_NODE, &set_metric_cmd);
1155: install_element (RMAP_NODE, &no_set_metric_cmd);
1156:
1157: /* ASE Metric */
1158: install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
1159: install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
1160: }
1161:
1162:
1163: /* Display functions */
1164: static int
1165: ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
1166: {
1167: struct ospf6_as_external_lsa *external;
1168: char buf[64];
1169: struct in6_addr in6, *forwarding;
1170:
1171: assert (lsa->header);
1172: external = (struct ospf6_as_external_lsa *)
1173: OSPF6_LSA_HEADER_END (lsa->header);
1174:
1175: /* bits */
1176: snprintf (buf, sizeof (buf), "%c%c%c",
1177: (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
1178: (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
1179: (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
1180:
1181: vty_out (vty, " Bits: %s%s", buf, VNL);
1182: vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
1183: VNL);
1184:
1185: ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1186: buf, sizeof (buf));
1187: vty_out (vty, " Prefix Options: %s%s", buf,
1188: VNL);
1189:
1190: vty_out (vty, " Referenced LSType: %d%s",
1191: ntohs (external->prefix.prefix_refer_lstype),
1192: VNL);
1193:
1194: ospf6_prefix_in6_addr (&in6, &external->prefix);
1195: inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
1196: vty_out (vty, " Prefix: %s/%d%s", buf,
1197: external->prefix.prefix_length, VNL);
1198:
1199: /* Forwarding-Address */
1200: if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
1201: {
1202: forwarding = (struct in6_addr *)
1203: ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
1204: OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
1205: inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
1206: vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
1207: }
1208:
1209: return 0;
1210: }
1211:
1212: static void
1213: ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
1214: {
1215: struct ospf6_external_info *info = route->route_option;
1216: char prefix[64], id[16], forwarding[64];
1217: u_int32_t tmp_id;
1218:
1219: prefix2str (&route->prefix, prefix, sizeof (prefix));
1220: tmp_id = ntohl (info->id);
1221: inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
1222: if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
1223: inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
1224: else
1225: snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
1226: route->nexthop[0].ifindex);
1227:
1228: vty_out (vty, "%c %-32s %-15s type-%d %5lu %s%s",
1229: zebra_route_char(info->type),
1230: prefix, id, route->path.metric_type,
1231: (u_long) (route->path.metric_type == 2 ?
1232: route->path.cost_e2 : route->path.cost),
1233: forwarding, VNL);
1234: }
1235:
1236: DEFUN (show_ipv6_ospf6_redistribute,
1237: show_ipv6_ospf6_redistribute_cmd,
1238: "show ipv6 ospf6 redistribute",
1239: SHOW_STR
1240: IP6_STR
1241: OSPF6_STR
1242: "redistributing External information\n"
1243: )
1244: {
1245: struct ospf6_route *route;
1246:
1247: ospf6_redistribute_show_config (vty);
1248:
1249: for (route = ospf6_route_head (ospf6->external_table); route;
1250: route = ospf6_route_next (route))
1251: ospf6_asbr_external_route_show (vty, route);
1252:
1253: return CMD_SUCCESS;
1254: }
1255:
1256: struct ospf6_lsa_handler as_external_handler =
1257: {
1258: OSPF6_LSTYPE_AS_EXTERNAL,
1259: "AS-External",
1260: ospf6_as_external_lsa_show
1261: };
1262:
1263: void
1264: ospf6_asbr_init (void)
1265: {
1266: ospf6_routemap_init ();
1267:
1268: ospf6_install_lsa_handler (&as_external_handler);
1269:
1270: install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
1271: install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
1272:
1273: install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
1274: install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
1275: install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
1276: }
1277:
1278: void
1279: ospf6_asbr_terminate (void)
1280: {
1281: route_map_finish ();
1282: }
1283:
1284: DEFUN (debug_ospf6_asbr,
1285: debug_ospf6_asbr_cmd,
1286: "debug ospf6 asbr",
1287: DEBUG_STR
1288: OSPF6_STR
1289: "Debug OSPFv3 ASBR function\n"
1290: )
1291: {
1292: OSPF6_DEBUG_ASBR_ON ();
1293: return CMD_SUCCESS;
1294: }
1295:
1296: DEFUN (no_debug_ospf6_asbr,
1297: no_debug_ospf6_asbr_cmd,
1298: "no debug ospf6 asbr",
1299: NO_STR
1300: DEBUG_STR
1301: OSPF6_STR
1302: "Debug OSPFv3 ASBR function\n"
1303: )
1304: {
1305: OSPF6_DEBUG_ASBR_OFF ();
1306: return CMD_SUCCESS;
1307: }
1308:
1309: int
1310: config_write_ospf6_debug_asbr (struct vty *vty)
1311: {
1312: if (IS_OSPF6_DEBUG_ASBR)
1313: vty_out (vty, "debug ospf6 asbr%s", VNL);
1314: return 0;
1315: }
1316:
1317: void
1318: install_element_ospf6_debug_asbr ()
1319: {
1320: install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
1321: install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
1322: install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
1323: install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
1324: }
1325:
1326:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>