2 * Copyright (C) 2003 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
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
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.
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.
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"
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"
51 unsigned char conf_debug_ospf6_asbr
= 0;
53 #define ZROUTE_NAME(x) zebra_route_string(x)
55 /* AS External LSA origination */
57 ospf6_as_external_lsa_originate (struct ospf6_route
*route
)
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
;
64 struct ospf6_as_external_lsa
*as_external_lsa
;
68 /* find previous LSA */
69 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL
),
70 route
->path
.origin
.id
, ospf6
->router_id
,
73 if (IS_OSPF6_DEBUG_ASBR
|| IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL
))
75 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
76 zlog_debug ("Originate AS-External-LSA for %s", buf
);
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
));
85 ((caddr_t
) as_external_lsa
+ sizeof (struct ospf6_as_external_lsa
));
87 /* Fill AS-External-LSA */
89 if (route
->path
.metric_type
== 2)
90 SET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_E
);
92 UNSET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_E
);
94 /* forwarding address */
95 if (! IN6_IS_ADDR_UNSPECIFIED (&info
->forwarding
))
96 SET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_F
);
98 UNSET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_F
);
100 /* external route tag */
101 UNSET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_T
);
104 OSPF6_ASBR_METRIC_SET (as_external_lsa
, route
->path
.cost
);
107 as_external_lsa
->prefix
.prefix_length
= route
->prefix
.prefixlen
;
110 as_external_lsa
->prefix
.prefix_options
= route
->path
.prefix_options
;
112 /* don't use refer LS-type */
113 as_external_lsa
->prefix
.prefix_refer_lstype
= htons (0);
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
);
121 /* Forwarding address */
122 if (CHECK_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_F
))
124 memcpy (p
, &info
->forwarding
, sizeof (struct in6_addr
));
125 p
+= sizeof (struct in6_addr
);
128 /* External Route Tag */
129 if (CHECK_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_T
))
134 /* Fill LSA Header */
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
;
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
);
145 ospf6_lsa_checksum (lsa_header
);
148 lsa
= ospf6_lsa_create (lsa_header
);
151 ospf6_lsa_originate_process (lsa
, ospf6
);
156 ospf6_asbr_lsa_add (struct ospf6_lsa
*lsa
)
158 struct ospf6_as_external_lsa
*external
;
159 struct prefix asbr_id
;
160 struct ospf6_route
*asbr_entry
, *route
;
164 external
= (struct ospf6_as_external_lsa
*)
165 OSPF6_LSA_HEADER_END (lsa
->header
);
167 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
168 zlog_debug ("Calculate AS-External route for %s", lsa
->name
);
170 if (lsa
->header
->adv_router
== ospf6
->router_id
)
172 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
173 zlog_debug ("Ignore self-originated AS-External-LSA");
177 if (OSPF6_ASBR_METRIC (external
) == LS_INFINITY
)
179 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
180 zlog_debug ("Ignore LSA with LSInfinity Metric");
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
))
189 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
191 prefix2str (&asbr_id
, buf
, sizeof (buf
));
192 zlog_debug ("ASBR entry not found: %s", buf
);
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
);
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
;
208 route
->path
.prefix_options
= external
->prefix
.prefix_options
;
209 if (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_E
))
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
);
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;
224 for (i
= 0; i
< OSPF6_MULTI_PATH_LIMIT
; i
++)
225 ospf6_nexthop_copy (&route
->nexthop
[i
], &asbr_entry
->nexthop
[i
]);
227 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
229 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
230 zlog_debug ("AS-External route add: %s", buf
);
233 ospf6_route_add (route
, ospf6
->route_table
);
237 ospf6_asbr_lsa_remove (struct ospf6_lsa
*lsa
)
239 struct ospf6_as_external_lsa
*external
;
240 struct prefix prefix
;
241 struct ospf6_route
*route
;
244 external
= (struct ospf6_as_external_lsa
*)
245 OSPF6_LSA_HEADER_END (lsa
->header
);
247 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
248 zlog_debug ("Withdraw AS-External route for %s", lsa
->name
);
250 if (lsa
->header
->adv_router
== ospf6
->router_id
)
252 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
253 zlog_debug ("Ignore self-originated AS-External-LSA");
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
);
262 route
= ospf6_route_lookup (&prefix
, ospf6
->route_table
);
265 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
267 prefix2str (&prefix
, buf
, sizeof (buf
));
268 zlog_debug ("AS-External route %s not found", buf
);
273 for (ospf6_route_lock (route
);
274 route
&& ospf6_route_is_prefix (&prefix
, route
);
275 route
= ospf6_route_next (route
))
277 if (route
->type
!= OSPF6_DEST_TYPE_NETWORK
)
279 if (route
->path
.origin
.type
!= lsa
->header
->type
)
281 if (route
->path
.origin
.id
!= lsa
->header
->id
)
283 if (route
->path
.origin
.adv_router
!= lsa
->header
->adv_router
)
286 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
288 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
289 zlog_debug ("AS-External route remove: %s", buf
);
291 ospf6_route_remove (route
, ospf6
->route_table
);
296 ospf6_asbr_lsentry_add (struct ospf6_route
*asbr_entry
)
298 struct ospf6_lsa
*lsa
;
302 if (! CHECK_FLAG (asbr_entry
->flag
, OSPF6_ROUTE_BEST
))
305 inet_ntop (AF_INET
, &ADV_ROUTER_IN_PREFIX (&asbr_entry
->prefix
),
307 zlog_info ("ignore non-best path: lsentry %s add", buf
);
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
))
316 if (! OSPF6_LSA_IS_MAXAGE (lsa
))
317 ospf6_asbr_lsa_add (lsa
);
322 ospf6_asbr_lsentry_remove (struct ospf6_route
*asbr_entry
)
324 struct ospf6_lsa
*lsa
;
328 if (! CHECK_FLAG (asbr_entry
->flag
, OSPF6_ROUTE_BEST
))
331 inet_ntop (AF_INET
, &ADV_ROUTER_IN_PREFIX (&asbr_entry
->prefix
),
333 zlog_info ("ignore non-best path: lsentry %s remove", buf
);
337 type
= htons (OSPF6_LSTYPE_AS_EXTERNAL
);
338 router
= ospf6_linkstate_prefix_adv_router (&asbr_entry
->prefix
);
339 for (lsa
= ospf6_lsdb_type_router_head (type
, router
, ospf6
->lsdb
);
340 lsa
; lsa
= ospf6_lsdb_type_router_next (type
, router
, lsa
))
341 ospf6_asbr_lsa_remove (lsa
);
346 /* redistribute function */
349 ospf6_asbr_routemap_set (int type
, const char *mapname
)
351 if (ospf6
->rmap
[type
].name
)
352 free (ospf6
->rmap
[type
].name
);
353 ospf6
->rmap
[type
].name
= strdup (mapname
);
354 ospf6
->rmap
[type
].map
= route_map_lookup_by_name (mapname
);
358 ospf6_asbr_routemap_unset (int type
)
360 if (ospf6
->rmap
[type
].name
)
361 free (ospf6
->rmap
[type
].name
);
362 ospf6
->rmap
[type
].name
= NULL
;
363 ospf6
->rmap
[type
].map
= NULL
;
367 ospf6_asbr_routemap_update (const char *mapname
)
374 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++)
376 if (ospf6
->rmap
[type
].name
)
377 ospf6
->rmap
[type
].map
=
378 route_map_lookup_by_name (ospf6
->rmap
[type
].name
);
380 ospf6
->rmap
[type
].map
= NULL
;
385 ospf6_asbr_is_asbr (struct ospf6
*o
)
387 return o
->external_table
->count
;
391 ospf6_asbr_redistribute_set (int type
)
393 ospf6_zebra_redistribute (type
);
397 ospf6_asbr_redistribute_unset (int type
)
399 struct ospf6_route
*route
;
400 struct ospf6_external_info
*info
;
402 ospf6_zebra_no_redistribute (type
);
404 for (route
= ospf6_route_head (ospf6
->external_table
); route
;
405 route
= ospf6_route_next (route
))
407 info
= route
->route_option
;
408 if (info
->type
!= type
)
411 ospf6_asbr_redistribute_remove (info
->type
, route
->nexthop
[0].ifindex
,
417 ospf6_asbr_redistribute_add (int type
, int ifindex
, struct prefix
*prefix
,
418 u_int nexthop_num
, struct in6_addr
*nexthop
)
421 struct ospf6_route troute
;
422 struct ospf6_external_info tinfo
;
423 struct ospf6_route
*route
, *match
;
424 struct ospf6_external_info
*info
;
425 struct prefix prefix_id
;
426 struct route_node
*node
;
427 char pbuf
[64], ibuf
[16];
428 struct listnode
*lnode
, *lnnode
;
429 struct ospf6_area
*oa
;
431 if (! ospf6_zebra_is_redistribute (type
))
434 if (IS_OSPF6_DEBUG_ASBR
)
436 prefix2str (prefix
, pbuf
, sizeof (pbuf
));
437 zlog_debug ("Redistribute %s (%s)", pbuf
, ZROUTE_NAME (type
));
440 /* if route-map was specified but not found, do not advertise */
441 if (ospf6
->rmap
[type
].name
)
443 if (ospf6
->rmap
[type
].map
== NULL
)
444 ospf6_asbr_routemap_update (NULL
);
445 if (ospf6
->rmap
[type
].map
== NULL
)
447 zlog_warn ("route-map \"%s\" not found, suppress redistributing",
448 ospf6
->rmap
[type
].name
);
453 /* apply route-map */
454 if (ospf6
->rmap
[type
].map
)
456 memset (&troute
, 0, sizeof (troute
));
457 memset (&tinfo
, 0, sizeof (tinfo
));
458 troute
.route_option
= &tinfo
;
460 ret
= route_map_apply (ospf6
->rmap
[type
].map
, prefix
,
461 RMAP_OSPF6
, &troute
);
462 if (ret
== RMAP_DENYMATCH
)
464 if (IS_OSPF6_DEBUG_ASBR
)
465 zlog_debug ("Denied by route-map \"%s\"", ospf6
->rmap
[type
].name
);
470 match
= ospf6_route_lookup (prefix
, ospf6
->external_table
);
473 info
= match
->route_option
;
475 /* copy result of route-map */
476 if (ospf6
->rmap
[type
].map
)
478 if (troute
.path
.metric_type
)
479 match
->path
.metric_type
= troute
.path
.metric_type
;
480 if (troute
.path
.cost
)
481 match
->path
.cost
= troute
.path
.cost
;
482 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo
.forwarding
))
483 memcpy (&info
->forwarding
, &tinfo
.forwarding
,
484 sizeof (struct in6_addr
));
488 match
->nexthop
[0].ifindex
= ifindex
;
489 if (nexthop_num
&& nexthop
)
490 memcpy (&match
->nexthop
[0].address
, nexthop
, sizeof (struct in6_addr
));
492 /* create/update binding in external_id_table */
493 prefix_id
.family
= AF_INET
;
494 prefix_id
.prefixlen
= 32;
495 prefix_id
.u
.prefix4
.s_addr
= htonl (info
->id
);
496 node
= route_node_get (ospf6
->external_id_table
, &prefix_id
);
499 if (IS_OSPF6_DEBUG_ASBR
)
501 inet_ntop (AF_INET
, &prefix_id
.u
.prefix4
, ibuf
, sizeof (ibuf
));
502 zlog_debug ("Advertise as AS-External Id:%s", ibuf
);
505 match
->path
.origin
.id
= htonl (info
->id
);
506 ospf6_as_external_lsa_originate (match
);
510 /* create new entry */
511 route
= ospf6_route_create ();
512 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
513 memcpy (&route
->prefix
, prefix
, sizeof (struct prefix
));
515 info
= (struct ospf6_external_info
*)
516 XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO
, sizeof (struct ospf6_external_info
));
517 memset (info
, 0, sizeof (struct ospf6_external_info
));
518 route
->route_option
= info
;
519 info
->id
= ospf6
->external_id
++;
521 /* copy result of route-map */
522 if (ospf6
->rmap
[type
].map
)
524 if (troute
.path
.metric_type
)
525 route
->path
.metric_type
= troute
.path
.metric_type
;
526 if (troute
.path
.cost
)
527 route
->path
.cost
= troute
.path
.cost
;
528 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo
.forwarding
))
529 memcpy (&info
->forwarding
, &tinfo
.forwarding
,
530 sizeof (struct in6_addr
));
534 route
->nexthop
[0].ifindex
= ifindex
;
535 if (nexthop_num
&& nexthop
)
536 memcpy (&route
->nexthop
[0].address
, nexthop
, sizeof (struct in6_addr
));
538 /* create/update binding in external_id_table */
539 prefix_id
.family
= AF_INET
;
540 prefix_id
.prefixlen
= 32;
541 prefix_id
.u
.prefix4
.s_addr
= htonl (info
->id
);
542 node
= route_node_get (ospf6
->external_id_table
, &prefix_id
);
545 route
= ospf6_route_add (route
, ospf6
->external_table
);
546 route
->route_option
= info
;
548 if (IS_OSPF6_DEBUG_ASBR
)
550 inet_ntop (AF_INET
, &prefix_id
.u
.prefix4
, ibuf
, sizeof (ibuf
));
551 zlog_debug ("Advertise as AS-External Id:%s", ibuf
);
554 route
->path
.origin
.id
= htonl (info
->id
);
555 ospf6_as_external_lsa_originate (route
);
557 /* Router-Bit (ASBR Flag) may have to be updated */
558 for (ALL_LIST_ELEMENTS (ospf6
->area_list
, lnode
, lnnode
, oa
))
559 OSPF6_ROUTER_LSA_SCHEDULE (oa
);
563 ospf6_asbr_redistribute_remove (int type
, int ifindex
, struct prefix
*prefix
)
565 struct ospf6_route
*match
;
566 struct ospf6_external_info
*info
= NULL
;
567 struct route_node
*node
;
568 struct ospf6_lsa
*lsa
;
569 struct prefix prefix_id
;
570 char pbuf
[64], ibuf
[16];
571 struct listnode
*lnode
, *lnnode
;
572 struct ospf6_area
*oa
;
574 match
= ospf6_route_lookup (prefix
, ospf6
->external_table
);
577 if (IS_OSPF6_DEBUG_ASBR
)
579 prefix2str (prefix
, pbuf
, sizeof (pbuf
));
580 zlog_debug ("No such route %s to withdraw", pbuf
);
585 info
= match
->route_option
;
588 if (info
->type
!= type
)
590 if (IS_OSPF6_DEBUG_ASBR
)
592 prefix2str (prefix
, pbuf
, sizeof (pbuf
));
593 zlog_debug ("Original protocol mismatch: %s", pbuf
);
598 if (IS_OSPF6_DEBUG_ASBR
)
600 prefix2str (prefix
, pbuf
, sizeof (pbuf
));
601 inet_ntop (AF_INET
, &prefix_id
.u
.prefix4
, ibuf
, sizeof (ibuf
));
602 zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf
, ibuf
);
605 lsa
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL
),
606 htonl (info
->id
), ospf6
->router_id
, ospf6
->lsdb
);
608 ospf6_lsa_purge (lsa
);
610 /* remove binding in external_id_table */
611 prefix_id
.family
= AF_INET
;
612 prefix_id
.prefixlen
= 32;
613 prefix_id
.u
.prefix4
.s_addr
= htonl (info
->id
);
614 node
= route_node_lookup (ospf6
->external_id_table
, &prefix_id
);
617 route_unlock_node (node
);
619 ospf6_route_remove (match
, ospf6
->external_table
);
620 XFREE (MTYPE_OSPF6_EXTERNAL_INFO
, info
);
622 /* Router-Bit (ASBR Flag) may have to be updated */
623 for (ALL_LIST_ELEMENTS (ospf6
->area_list
, lnode
, lnnode
, oa
))
624 OSPF6_ROUTER_LSA_SCHEDULE (oa
);
627 DEFUN (ospf6_redistribute
,
628 ospf6_redistribute_cmd
,
629 "redistribute (static|kernel|connected|ripng|bgp)",
640 if (strncmp (argv
[0], "sta", 3) == 0)
641 type
= ZEBRA_ROUTE_STATIC
;
642 else if (strncmp (argv
[0], "ker", 3) == 0)
643 type
= ZEBRA_ROUTE_KERNEL
;
644 else if (strncmp (argv
[0], "con", 3) == 0)
645 type
= ZEBRA_ROUTE_CONNECT
;
646 else if (strncmp (argv
[0], "rip", 3) == 0)
647 type
= ZEBRA_ROUTE_RIPNG
;
648 else if (strncmp (argv
[0], "bgp", 3) == 0)
649 type
= ZEBRA_ROUTE_BGP
;
651 ospf6_asbr_redistribute_unset (type
);
652 ospf6_asbr_routemap_unset (type
);
653 ospf6_asbr_redistribute_set (type
);
657 DEFUN (ospf6_redistribute_routemap
,
658 ospf6_redistribute_routemap_cmd
,
659 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
666 "Route map reference\n"
672 if (strncmp (argv
[0], "sta", 3) == 0)
673 type
= ZEBRA_ROUTE_STATIC
;
674 else if (strncmp (argv
[0], "ker", 3) == 0)
675 type
= ZEBRA_ROUTE_KERNEL
;
676 else if (strncmp (argv
[0], "con", 3) == 0)
677 type
= ZEBRA_ROUTE_CONNECT
;
678 else if (strncmp (argv
[0], "rip", 3) == 0)
679 type
= ZEBRA_ROUTE_RIPNG
;
680 else if (strncmp (argv
[0], "bgp", 3) == 0)
681 type
= ZEBRA_ROUTE_BGP
;
683 ospf6_asbr_redistribute_unset (type
);
684 ospf6_asbr_routemap_set (type
, argv
[1]);
685 ospf6_asbr_redistribute_set (type
);
689 DEFUN (no_ospf6_redistribute
,
690 no_ospf6_redistribute_cmd
,
691 "no redistribute (static|kernel|connected|ripng|bgp)",
703 if (strncmp (argv
[0], "sta", 3) == 0)
704 type
= ZEBRA_ROUTE_STATIC
;
705 else if (strncmp (argv
[0], "ker", 3) == 0)
706 type
= ZEBRA_ROUTE_KERNEL
;
707 else if (strncmp (argv
[0], "con", 3) == 0)
708 type
= ZEBRA_ROUTE_CONNECT
;
709 else if (strncmp (argv
[0], "rip", 3) == 0)
710 type
= ZEBRA_ROUTE_RIPNG
;
711 else if (strncmp (argv
[0], "bgp", 3) == 0)
712 type
= ZEBRA_ROUTE_BGP
;
714 ospf6_asbr_redistribute_unset (type
);
715 ospf6_asbr_routemap_unset (type
);
721 ospf6_redistribute_config_write (struct vty
*vty
)
725 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++)
727 if (type
== ZEBRA_ROUTE_OSPF6
)
729 if (! ospf6_zebra_is_redistribute (type
))
732 if (ospf6
->rmap
[type
].name
)
733 vty_out (vty
, " redistribute %s route-map %s%s",
734 ZROUTE_NAME (type
), ospf6
->rmap
[type
].name
, VNL
);
736 vty_out (vty
, " redistribute %s%s",
737 ZROUTE_NAME (type
), VNL
);
744 ospf6_redistribute_show_config (struct vty
*vty
)
747 int nroute
[ZEBRA_ROUTE_MAX
];
749 struct ospf6_route
*route
;
750 struct ospf6_external_info
*info
;
753 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++)
755 for (route
= ospf6_route_head (ospf6
->external_table
); route
;
756 route
= ospf6_route_next (route
))
758 info
= route
->route_option
;
759 nroute
[info
->type
]++;
763 vty_out (vty
, "Redistributing External Routes from:%s", VNL
);
764 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++)
766 if (type
== ZEBRA_ROUTE_OSPF6
)
768 if (! ospf6_zebra_is_redistribute (type
))
771 if (ospf6
->rmap
[type
].name
)
772 vty_out (vty
, " %d: %s with route-map \"%s\"%s%s", nroute
[type
],
773 ZROUTE_NAME (type
), ospf6
->rmap
[type
].name
,
774 (ospf6
->rmap
[type
].map
? "" : " (not found !)"),
777 vty_out (vty
, " %d: %s%s", nroute
[type
],
778 ZROUTE_NAME (type
), VNL
);
780 vty_out (vty
, "Total %d routes%s", total
, VNL
);
785 /* Routemap Functions */
787 ospf6_routemap_rule_match_address_prefixlist (void *rule
,
788 struct prefix
*prefix
,
789 route_map_object_t type
,
792 struct prefix_list
*plist
;
794 if (type
!= RMAP_OSPF6
)
797 plist
= prefix_list_lookup (AFI_IP6
, (char *) rule
);
801 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
802 RMAP_NOMATCH
: RMAP_MATCH
);
806 ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg
)
808 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
812 ospf6_routemap_rule_match_address_prefixlist_free (void *rule
)
814 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
817 struct route_map_rule_cmd
818 ospf6_routemap_rule_match_address_prefixlist_cmd
=
820 "ipv6 address prefix-list",
821 ospf6_routemap_rule_match_address_prefixlist
,
822 ospf6_routemap_rule_match_address_prefixlist_compile
,
823 ospf6_routemap_rule_match_address_prefixlist_free
,
827 ospf6_routemap_rule_set_metric_type (void *rule
, struct prefix
*prefix
,
828 route_map_object_t type
, void *object
)
830 char *metric_type
= rule
;
831 struct ospf6_route
*route
= object
;
833 if (type
!= RMAP_OSPF6
)
836 if (strcmp (metric_type
, "type-2") == 0)
837 route
->path
.metric_type
= 2;
839 route
->path
.metric_type
= 1;
845 ospf6_routemap_rule_set_metric_type_compile (const char *arg
)
847 if (strcmp (arg
, "type-2") && strcmp (arg
, "type-1"))
849 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
853 ospf6_routemap_rule_set_metric_type_free (void *rule
)
855 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
858 struct route_map_rule_cmd
859 ospf6_routemap_rule_set_metric_type_cmd
=
862 ospf6_routemap_rule_set_metric_type
,
863 ospf6_routemap_rule_set_metric_type_compile
,
864 ospf6_routemap_rule_set_metric_type_free
,
868 ospf6_routemap_rule_set_metric (void *rule
, struct prefix
*prefix
,
869 route_map_object_t type
, void *object
)
872 struct ospf6_route
*route
= object
;
874 if (type
!= RMAP_OSPF6
)
877 route
->path
.cost
= atoi (metric
);
882 ospf6_routemap_rule_set_metric_compile (const char *arg
)
886 metric
= strtoul (arg
, &endp
, 0);
887 if (metric
> LS_INFINITY
|| *endp
!= '\0')
889 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
893 ospf6_routemap_rule_set_metric_free (void *rule
)
895 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
898 struct route_map_rule_cmd
899 ospf6_routemap_rule_set_metric_cmd
=
902 ospf6_routemap_rule_set_metric
,
903 ospf6_routemap_rule_set_metric_compile
,
904 ospf6_routemap_rule_set_metric_free
,
908 ospf6_routemap_rule_set_forwarding (void *rule
, struct prefix
*prefix
,
909 route_map_object_t type
, void *object
)
911 char *forwarding
= rule
;
912 struct ospf6_route
*route
= object
;
913 struct ospf6_external_info
*info
= route
->route_option
;
915 if (type
!= RMAP_OSPF6
)
918 if (inet_pton (AF_INET6
, forwarding
, &info
->forwarding
) != 1)
920 memset (&info
->forwarding
, 0, sizeof (struct in6_addr
));
928 ospf6_routemap_rule_set_forwarding_compile (const char *arg
)
931 if (inet_pton (AF_INET6
, arg
, &a
) != 1)
933 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
937 ospf6_routemap_rule_set_forwarding_free (void *rule
)
939 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
942 struct route_map_rule_cmd
943 ospf6_routemap_rule_set_forwarding_cmd
=
945 "forwarding-address",
946 ospf6_routemap_rule_set_forwarding
,
947 ospf6_routemap_rule_set_forwarding_compile
,
948 ospf6_routemap_rule_set_forwarding_free
,
952 route_map_command_status (struct vty
*vty
, int ret
)
959 case RMAP_RULE_MISSING
:
960 vty_out (vty
, "Can't find rule.%s", VNL
);
962 case RMAP_COMPILE_ERROR
:
963 vty_out (vty
, "Argument is malformed.%s", VNL
);
966 vty_out (vty
, "route-map add set failed.%s", VNL
);
972 /* add "match address" */
973 DEFUN (ospf6_routemap_match_address_prefixlist
,
974 ospf6_routemap_match_address_prefixlist_cmd
,
975 "match ipv6 address prefix-list WORD",
978 "Match address of route\n"
979 "Match entries of prefix-lists\n"
980 "IPv6 prefix-list name\n")
982 int ret
= route_map_add_match ((struct route_map_index
*) vty
->index
,
983 "ipv6 address prefix-list", argv
[0]);
984 return route_map_command_status (vty
, ret
);
987 /* delete "match address" */
988 DEFUN (ospf6_routemap_no_match_address_prefixlist
,
989 ospf6_routemap_no_match_address_prefixlist_cmd
,
990 "no match ipv6 address prefix-list WORD",
994 "Match address of route\n"
995 "Match entries of prefix-lists\n"
996 "IPv6 prefix-list name\n")
998 int ret
= route_map_delete_match ((struct route_map_index
*) vty
->index
,
999 "ipv6 address prefix-list", argv
[0]);
1000 return route_map_command_status (vty
, ret
);
1003 /* add "set metric-type" */
1004 DEFUN (ospf6_routemap_set_metric_type
,
1005 ospf6_routemap_set_metric_type_cmd
,
1006 "set metric-type (type-1|type-2)",
1009 "OSPF6 external type 1 metric\n"
1010 "OSPF6 external type 2 metric\n")
1012 int ret
= route_map_add_set ((struct route_map_index
*) vty
->index
,
1013 "metric-type", argv
[0]);
1014 return route_map_command_status (vty
, ret
);
1017 /* delete "set metric-type" */
1018 DEFUN (ospf6_routemap_no_set_metric_type
,
1019 ospf6_routemap_no_set_metric_type_cmd
,
1020 "no set metric-type (type-1|type-2)",
1024 "OSPF6 external type 1 metric\n"
1025 "OSPF6 external type 2 metric\n")
1027 int ret
= route_map_delete_set ((struct route_map_index
*) vty
->index
,
1028 "metric-type", argv
[0]);
1029 return route_map_command_status (vty
, ret
);
1032 /* add "set metric" */
1035 "set metric <0-4294967295>",
1040 int ret
= route_map_add_set ((struct route_map_index
*) vty
->index
,
1042 return route_map_command_status (vty
, ret
);
1045 /* delete "set metric" */
1046 DEFUN (no_set_metric
,
1048 "no set metric <0-4294967295>",
1054 int ret
= route_map_delete_set ((struct route_map_index
*) vty
->index
,
1056 return route_map_command_status (vty
, ret
);
1059 /* add "set forwarding-address" */
1060 DEFUN (ospf6_routemap_set_forwarding
,
1061 ospf6_routemap_set_forwarding_cmd
,
1062 "set forwarding-address X:X::X:X",
1064 "Forwarding Address\n"
1067 int ret
= route_map_add_set ((struct route_map_index
*) vty
->index
,
1068 "forwarding-address", argv
[0]);
1069 return route_map_command_status (vty
, ret
);
1072 /* delete "set forwarding-address" */
1073 DEFUN (ospf6_routemap_no_set_forwarding
,
1074 ospf6_routemap_no_set_forwarding_cmd
,
1075 "no set forwarding-address X:X::X:X",
1078 "Forwarding Address\n"
1081 int ret
= route_map_delete_set ((struct route_map_index
*) vty
->index
,
1082 "forwarding-address", argv
[0]);
1083 return route_map_command_status (vty
, ret
);
1087 ospf6_routemap_init ()
1090 route_map_init_vty ();
1091 route_map_add_hook (ospf6_asbr_routemap_update
);
1092 route_map_delete_hook (ospf6_asbr_routemap_update
);
1094 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd
);
1095 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd
);
1096 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd
);
1097 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd
);
1099 /* Match address prefix-list */
1100 install_element (RMAP_NODE
, &ospf6_routemap_match_address_prefixlist_cmd
);
1101 install_element (RMAP_NODE
, &ospf6_routemap_no_match_address_prefixlist_cmd
);
1103 /* ASE Metric Type (e.g. Type-1/Type-2) */
1104 install_element (RMAP_NODE
, &ospf6_routemap_set_metric_type_cmd
);
1105 install_element (RMAP_NODE
, &ospf6_routemap_no_set_metric_type_cmd
);
1108 install_element (RMAP_NODE
, &set_metric_cmd
);
1109 install_element (RMAP_NODE
, &no_set_metric_cmd
);
1112 install_element (RMAP_NODE
, &ospf6_routemap_set_forwarding_cmd
);
1113 install_element (RMAP_NODE
, &ospf6_routemap_no_set_forwarding_cmd
);
1117 /* Display functions */
1119 ospf6_as_external_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
1121 struct ospf6_as_external_lsa
*external
;
1123 struct in6_addr in6
, *forwarding
;
1125 assert (lsa
->header
);
1126 external
= (struct ospf6_as_external_lsa
*)
1127 OSPF6_LSA_HEADER_END (lsa
->header
);
1130 snprintf (buf
, sizeof (buf
), "%c%c%c",
1131 (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_E
) ? 'E' : '-'),
1132 (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_F
) ? 'F' : '-'),
1133 (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_T
) ? 'T' : '-'));
1135 vty_out (vty
, " Bits: %s%s", buf
, VNL
);
1136 vty_out (vty
, " Metric: %5lu%s", (u_long
) OSPF6_ASBR_METRIC (external
),
1139 ospf6_prefix_options_printbuf (external
->prefix
.prefix_options
,
1141 vty_out (vty
, " Prefix Options: %s%s", buf
,
1144 vty_out (vty
, " Referenced LSType: %d%s",
1145 ntohs (external
->prefix
.prefix_refer_lstype
),
1148 ospf6_prefix_in6_addr (&in6
, &external
->prefix
);
1149 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
1150 vty_out (vty
, " Prefix: %s/%d%s", buf
,
1151 external
->prefix
.prefix_length
, VNL
);
1153 /* Forwarding-Address */
1154 if (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_F
))
1156 forwarding
= (struct in6_addr
*)
1157 ((caddr_t
) external
+ sizeof (struct ospf6_as_external_lsa
) +
1158 OSPF6_PREFIX_SPACE (external
->prefix
.prefix_length
));
1159 inet_ntop (AF_INET6
, forwarding
, buf
, sizeof (buf
));
1160 vty_out (vty
, " Forwarding-Address: %s%s", buf
, VNL
);
1167 ospf6_asbr_external_route_show (struct vty
*vty
, struct ospf6_route
*route
)
1169 struct ospf6_external_info
*info
= route
->route_option
;
1170 char prefix
[64], id
[16], forwarding
[64];
1173 prefix2str (&route
->prefix
, prefix
, sizeof (prefix
));
1174 tmp_id
= ntohl (info
->id
);
1175 inet_ntop (AF_INET
, &tmp_id
, id
, sizeof (id
));
1176 if (! IN6_IS_ADDR_UNSPECIFIED (&info
->forwarding
))
1177 inet_ntop (AF_INET6
, &info
->forwarding
, forwarding
, sizeof (forwarding
));
1179 snprintf (forwarding
, sizeof (forwarding
), ":: (ifindex %d)",
1180 route
->nexthop
[0].ifindex
);
1182 vty_out (vty
, "%c %-32s %-15s type-%d %5lu %s%s",
1183 zebra_route_char(info
->type
),
1184 prefix
, id
, route
->path
.metric_type
,
1185 (u_long
) (route
->path
.metric_type
== 2 ?
1186 route
->path
.cost_e2
: route
->path
.cost
),
1190 DEFUN (show_ipv6_ospf6_redistribute
,
1191 show_ipv6_ospf6_redistribute_cmd
,
1192 "show ipv6 ospf6 redistribute",
1196 "redistributing External information\n"
1199 struct ospf6_route
*route
;
1201 ospf6_redistribute_show_config (vty
);
1203 for (route
= ospf6_route_head (ospf6
->external_table
); route
;
1204 route
= ospf6_route_next (route
))
1205 ospf6_asbr_external_route_show (vty
, route
);
1210 struct ospf6_lsa_handler as_external_handler
=
1212 OSPF6_LSTYPE_AS_EXTERNAL
,
1214 ospf6_as_external_lsa_show
1220 ospf6_routemap_init ();
1222 ospf6_install_lsa_handler (&as_external_handler
);
1224 install_element (VIEW_NODE
, &show_ipv6_ospf6_redistribute_cmd
);
1225 install_element (ENABLE_NODE
, &show_ipv6_ospf6_redistribute_cmd
);
1227 install_element (OSPF6_NODE
, &ospf6_redistribute_cmd
);
1228 install_element (OSPF6_NODE
, &ospf6_redistribute_routemap_cmd
);
1229 install_element (OSPF6_NODE
, &no_ospf6_redistribute_cmd
);
1233 DEFUN (debug_ospf6_asbr
,
1234 debug_ospf6_asbr_cmd
,
1238 "Debug OSPFv3 ASBR function\n"
1241 OSPF6_DEBUG_ASBR_ON ();
1245 DEFUN (no_debug_ospf6_asbr
,
1246 no_debug_ospf6_asbr_cmd
,
1247 "no debug ospf6 asbr",
1251 "Debug OSPFv3 ASBR function\n"
1254 OSPF6_DEBUG_ASBR_OFF ();
1259 config_write_ospf6_debug_asbr (struct vty
*vty
)
1261 if (IS_OSPF6_DEBUG_ASBR
)
1262 vty_out (vty
, "debug ospf6 asbr%s", VNL
);
1267 install_element_ospf6_debug_asbr ()
1269 install_element (ENABLE_NODE
, &debug_ospf6_asbr_cmd
);
1270 install_element (ENABLE_NODE
, &no_debug_ospf6_asbr_cmd
);
1271 install_element (CONFIG_NODE
, &debug_ospf6_asbr_cmd
);
1272 install_element (CONFIG_NODE
, &no_debug_ospf6_asbr_cmd
);