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;
54 { "system", "kernel", "connected", "static",
55 "rip", "ripng", "ospf", "ospf6", "bgp", "unknown" };
57 char *zroute_abname
[] =
58 { "X", "K", "C", "S", "R", "R", "O", "O", "B", "?" };
60 #define ZROUTE_NAME(x) \
61 (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? zroute_name[(x)] : \
62 zroute_name[ZEBRA_ROUTE_MAX])
63 #define ZROUTE_ABNAME(x) \
64 (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? zroute_abname[(x)] : \
65 zroute_abname[ZEBRA_ROUTE_MAX])
67 /* AS External LSA origination */
69 ospf6_as_external_lsa_originate (struct ospf6_route
*route
)
71 char buffer
[OSPF6_MAX_LSASIZE
];
72 struct ospf6_lsa_header
*lsa_header
;
73 struct ospf6_lsa
*old
, *lsa
;
75 struct ospf6_as_external_lsa
*as_external_lsa
;
79 /* find previous LSA */
80 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL
),
81 route
->path
.origin
.id
, ospf6
->router_id
,
84 if (IS_OSPF6_DEBUG_ASBR
|| IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL
))
86 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
87 zlog_info ("Originate AS-External-LSA for %s", buf
);
91 memset (buffer
, 0, sizeof (buffer
));
92 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
93 as_external_lsa
= (struct ospf6_as_external_lsa
*)
94 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
96 ((caddr_t
) as_external_lsa
+ sizeof (struct ospf6_as_external_lsa
));
98 /* Fill AS-External-LSA */
100 if (route
->path
.metric_type
== 2)
101 SET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_E
);
103 UNSET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_E
);
105 /* forwarding address */
106 if (! IN6_IS_ADDR_UNSPECIFIED (&route
->nexthop
[0].address
))
107 SET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_F
);
109 UNSET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_F
);
111 /* external route tag */
112 UNSET_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_T
);
115 OSPF6_ASBR_METRIC_SET (as_external_lsa
, route
->path
.cost
);
118 as_external_lsa
->prefix
.prefix_length
= route
->prefix
.prefixlen
;
121 as_external_lsa
->prefix
.prefix_options
= route
->path
.prefix_options
;
123 /* don't use refer LS-type */
124 as_external_lsa
->prefix
.prefix_refer_lstype
= htons (0);
127 memcpy (p
, &route
->prefix
.u
.prefix6
,
128 OSPF6_PREFIX_SPACE (route
->prefix
.prefixlen
));
129 ospf6_prefix_apply_mask (&as_external_lsa
->prefix
);
130 p
+= OSPF6_PREFIX_SPACE (route
->prefix
.prefixlen
);
132 /* Forwarding address */
133 if (CHECK_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_F
))
135 memcpy (p
, &route
->nexthop
[0].address
, sizeof (struct in6_addr
));
136 p
+= sizeof (struct in6_addr
);
139 /* External Route Tag */
140 if (CHECK_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_T
))
145 /* Fill LSA Header */
147 lsa_header
->type
= htons (OSPF6_LSTYPE_AS_EXTERNAL
);
148 lsa_header
->id
= route
->path
.origin
.id
;
149 lsa_header
->adv_router
= ospf6
->router_id
;
151 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
152 lsa_header
->adv_router
, ospf6
->lsdb
);
153 lsa_header
->length
= htons ((caddr_t
) p
- (caddr_t
) lsa_header
);
156 ospf6_lsa_checksum (lsa_header
);
159 lsa
= ospf6_lsa_create (lsa_header
);
162 ospf6_lsa_originate_process (lsa
, ospf6
);
167 ospf6_asbr_lsa_add (struct ospf6_lsa
*lsa
)
169 struct ospf6_as_external_lsa
*external
;
170 struct prefix asbr_id
;
171 struct ospf6_route
*asbr_entry
, *route
;
175 external
= (struct ospf6_as_external_lsa
*)
176 OSPF6_LSA_HEADER_END (lsa
->header
);
178 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
179 zlog_info ("Calculate AS-External route for %s", lsa
->name
);
181 if (lsa
->header
->adv_router
== ospf6
->router_id
)
183 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
184 zlog_info ("Ignore self-originated AS-External-LSA");
188 if (OSPF6_ASBR_METRIC (external
) == LS_INFINITY
)
190 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
191 zlog_info ("Ignore LSA with LSInfinity Metric");
195 ospf6_linkstate_prefix (lsa
->header
->adv_router
, htonl (0), &asbr_id
);
196 asbr_entry
= ospf6_route_lookup (&asbr_id
, ospf6
->brouter_table
);
197 if (asbr_entry
== NULL
||
198 ! CHECK_FLAG (asbr_entry
->path
.router_bits
, OSPF6_ROUTER_BIT_E
))
200 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
202 prefix2str (&asbr_id
, buf
, sizeof (buf
));
203 zlog_info ("ASBR entry not found: %s", buf
);
208 route
= ospf6_route_create ();
209 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
210 route
->prefix
.family
= AF_INET6
;
211 route
->prefix
.prefixlen
= external
->prefix
.prefix_length
;
212 ospf6_prefix_in6_addr (&route
->prefix
.u
.prefix6
, &external
->prefix
);
214 route
->path
.area_id
= asbr_entry
->path
.area_id
;
215 route
->path
.origin
.type
= lsa
->header
->type
;
216 route
->path
.origin
.id
= lsa
->header
->id
;
217 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
219 route
->path
.prefix_options
= external
->prefix
.prefix_options
;
220 if (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_E
))
222 route
->path
.type
= OSPF6_PATH_TYPE_EXTERNAL2
;
223 route
->path
.metric_type
= 2;
224 route
->path
.cost
= asbr_entry
->path
.cost
;
225 route
->path
.cost_e2
= OSPF6_ASBR_METRIC (external
);
229 route
->path
.type
= OSPF6_PATH_TYPE_EXTERNAL1
;
230 route
->path
.metric_type
= 1;
231 route
->path
.cost
= asbr_entry
->path
.cost
+ OSPF6_ASBR_METRIC (external
);
232 route
->path
.cost_e2
= 0;
235 for (i
= 0; i
< OSPF6_MULTI_PATH_LIMIT
; i
++)
236 ospf6_nexthop_copy (&route
->nexthop
[i
], &asbr_entry
->nexthop
[i
]);
238 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
240 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
241 zlog_info ("AS-External route add: %s", buf
);
244 ospf6_route_add (route
, ospf6
->route_table
);
248 ospf6_asbr_lsa_remove (struct ospf6_lsa
*lsa
)
250 struct ospf6_as_external_lsa
*external
;
251 struct prefix prefix
;
252 struct ospf6_route
*route
;
255 external
= (struct ospf6_as_external_lsa
*)
256 OSPF6_LSA_HEADER_END (lsa
->header
);
258 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
259 zlog_info ("Withdraw AS-External route for %s", lsa
->name
);
261 if (lsa
->header
->adv_router
== ospf6
->router_id
)
263 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
264 zlog_info ("Ignore self-originated AS-External-LSA");
268 memset (&prefix
, 0, sizeof (struct prefix
));
269 prefix
.family
= AF_INET6
;
270 prefix
.prefixlen
= external
->prefix
.prefix_length
;
271 ospf6_prefix_in6_addr (&prefix
.u
.prefix6
, &external
->prefix
);
273 route
= ospf6_route_lookup (&prefix
, ospf6
->route_table
);
276 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
278 prefix2str (&prefix
, buf
, sizeof (buf
));
279 zlog_info ("AS-External route %s not found", buf
);
284 for (ospf6_route_lock (route
);
285 route
&& ospf6_route_is_prefix (&prefix
, route
);
286 route
= ospf6_route_next (route
))
288 if (route
->type
!= OSPF6_DEST_TYPE_NETWORK
)
290 if (route
->path
.origin
.type
!= lsa
->header
->type
)
292 if (route
->path
.origin
.id
!= lsa
->header
->id
)
294 if (route
->path
.origin
.adv_router
!= lsa
->header
->adv_router
)
297 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
299 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
300 zlog_info ("AS-External route remove: %s", buf
);
302 ospf6_route_remove (route
, ospf6
->route_table
);
307 ospf6_asbr_lsentry_add (struct ospf6_route
*asbr_entry
)
310 struct ospf6_lsa
*lsa
;
314 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
316 ospf6_linkstate_prefix2str (&asbr_entry
->prefix
, buf
, sizeof (buf
));
317 zlog_info ("New ASBR %s found", buf
);
320 type
= htons (OSPF6_LSTYPE_AS_EXTERNAL
);
321 router
= ospf6_linkstate_prefix_adv_router (&asbr_entry
->prefix
);
322 for (lsa
= ospf6_lsdb_type_router_head (type
, router
, ospf6
->lsdb
);
323 lsa
; lsa
= ospf6_lsdb_type_router_next (type
, router
, lsa
))
325 if (! OSPF6_LSA_IS_MAXAGE (lsa
))
326 ospf6_asbr_lsa_add (lsa
);
329 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
331 ospf6_linkstate_prefix2str (&asbr_entry
->prefix
, buf
, sizeof (buf
));
332 zlog_info ("Calculation for new ASBR %s done", buf
);
337 ospf6_asbr_lsentry_remove (struct ospf6_route
*asbr_entry
)
340 struct ospf6_lsa
*lsa
;
344 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
346 ospf6_linkstate_prefix2str (&asbr_entry
->prefix
, buf
, sizeof (buf
));
347 zlog_info ("ASBR %s disappeared", buf
);
350 type
= htons (OSPF6_LSTYPE_AS_EXTERNAL
);
351 router
= ospf6_linkstate_prefix_adv_router (&asbr_entry
->prefix
);
352 for (lsa
= ospf6_lsdb_type_router_head (type
, router
, ospf6
->lsdb
);
353 lsa
; lsa
= ospf6_lsdb_type_router_next (type
, router
, lsa
))
354 ospf6_asbr_lsa_remove (lsa
);
356 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL
))
358 ospf6_linkstate_prefix2str (&asbr_entry
->prefix
, buf
, sizeof (buf
));
359 zlog_info ("Calculation for old ASBR %s done", buf
);
365 /* redistribute function */
368 ospf6_asbr_routemap_set (int type
, char *mapname
)
370 if (ospf6
->rmap
[type
].name
)
371 free (ospf6
->rmap
[type
].name
);
372 ospf6
->rmap
[type
].name
= strdup (mapname
);
373 ospf6
->rmap
[type
].map
= route_map_lookup_by_name (mapname
);
377 ospf6_asbr_routemap_unset (int type
)
379 if (ospf6
->rmap
[type
].name
)
380 free (ospf6
->rmap
[type
].name
);
381 ospf6
->rmap
[type
].name
= NULL
;
382 ospf6
->rmap
[type
].map
= NULL
;
386 ospf6_asbr_routemap_update (char *mapname
)
393 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++)
395 if (ospf6
->rmap
[type
].name
)
396 ospf6
->rmap
[type
].map
=
397 route_map_lookup_by_name (ospf6
->rmap
[type
].name
);
399 ospf6
->rmap
[type
].map
= NULL
;
404 ospf6_asbr_is_asbr (struct ospf6
*o
)
406 return o
->external_table
->count
;
410 ospf6_asbr_redistribute_set (int type
)
412 ospf6_zebra_redistribute (type
);
416 ospf6_asbr_redistribute_unset (int type
)
418 struct ospf6_route
*route
;
419 struct ospf6_external_info
*info
;
421 ospf6_zebra_no_redistribute (type
);
423 for (route
= ospf6_route_head (ospf6
->external_table
); route
;
424 route
= ospf6_route_next (route
))
426 info
= route
->route_option
;
427 if (info
->type
!= type
)
430 ospf6_asbr_redistribute_remove (info
->type
, route
->nexthop
[0].ifindex
,
436 ospf6_asbr_redistribute_add (int type
, int ifindex
, struct prefix
*prefix
,
437 u_int nexthop_num
, struct in6_addr
*nexthop
)
440 struct ospf6_route troute
;
441 struct ospf6_external_info tinfo
;
442 struct ospf6_route
*route
, *match
;
443 struct ospf6_external_info
*info
;
444 struct prefix prefix_id
;
445 struct route_node
*node
;
446 char pbuf
[64], ibuf
[16];
448 struct ospf6_area
*oa
;
450 if (! ospf6_zebra_is_redistribute (type
))
453 if (IS_OSPF6_DEBUG_ASBR
)
455 prefix2str (prefix
, pbuf
, sizeof (pbuf
));
456 zlog_info ("Redistribute %s (%s)", pbuf
, ZROUTE_NAME (type
));
459 /* if route-map was specified but not found, do not advertise */
460 if (ospf6
->rmap
[type
].name
)
462 if (ospf6
->rmap
[type
].map
== NULL
)
463 ospf6_asbr_routemap_update (NULL
);
464 if (ospf6
->rmap
[type
].map
== NULL
)
466 zlog_warn ("route-map \"%s\" not found, suppress redistributing",
467 ospf6
->rmap
[type
].name
);
472 /* apply route-map */
473 if (ospf6
->rmap
[type
].map
)
475 memset (&troute
, 0, sizeof (troute
));
476 memset (&tinfo
, 0, sizeof (tinfo
));
477 troute
.route_option
= &tinfo
;
479 ret
= route_map_apply (ospf6
->rmap
[type
].map
, prefix
,
480 RMAP_OSPF6
, &troute
);
481 if (ret
!= RMAP_MATCH
)
483 if (IS_OSPF6_DEBUG_ASBR
)
484 zlog_info ("Denied by route-map \"%s\"", ospf6
->rmap
[type
].name
);
489 match
= ospf6_route_lookup (prefix
, ospf6
->external_table
);
492 info
= match
->route_option
;
494 /* copy result of route-map */
495 if (ospf6
->rmap
[type
].map
)
497 if (troute
.path
.metric_type
)
498 match
->path
.metric_type
= troute
.path
.metric_type
;
499 if (troute
.path
.cost
)
500 match
->path
.cost
= troute
.path
.cost
;
501 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo
.forwarding
))
502 memcpy (&info
->forwarding
, &tinfo
.forwarding
,
503 sizeof (struct in6_addr
));
507 match
->nexthop
[0].ifindex
= ifindex
;
508 if (nexthop_num
&& nexthop
)
509 memcpy (&match
->nexthop
[0].address
, nexthop
, sizeof (struct in6_addr
));
511 /* create/update binding in external_id_table */
512 prefix_id
.family
= AF_INET
;
513 prefix_id
.prefixlen
= 32;
514 prefix_id
.u
.prefix4
.s_addr
= htonl (info
->id
);
515 node
= route_node_get (ospf6
->external_id_table
, &prefix_id
);
518 if (IS_OSPF6_DEBUG_ASBR
)
520 inet_ntop (AF_INET
, &prefix_id
.u
.prefix4
, ibuf
, sizeof (ibuf
));
521 zlog_info ("Advertise as AS-External Id:%s", ibuf
);
524 match
->path
.origin
.id
= htonl (info
->id
);
525 ospf6_as_external_lsa_originate (match
);
529 /* create new entry */
530 route
= ospf6_route_create ();
531 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
532 memcpy (&route
->prefix
, prefix
, sizeof (struct prefix
));
534 info
= (struct ospf6_external_info
*)
535 XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO
, sizeof (struct ospf6_external_info
));
536 memset (info
, 0, sizeof (struct ospf6_external_info
));
537 route
->route_option
= info
;
538 info
->id
= ospf6
->external_id
++;
540 /* copy result of route-map */
541 if (ospf6
->rmap
[type
].map
)
543 if (troute
.path
.metric_type
)
544 route
->path
.metric_type
= troute
.path
.metric_type
;
545 if (troute
.path
.cost
)
546 route
->path
.cost
= troute
.path
.cost
;
547 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo
.forwarding
))
548 memcpy (&info
->forwarding
, &tinfo
.forwarding
,
549 sizeof (struct in6_addr
));
553 route
->nexthop
[0].ifindex
= ifindex
;
554 if (nexthop_num
&& nexthop
)
555 memcpy (&route
->nexthop
[0].address
, nexthop
, sizeof (struct in6_addr
));
557 /* create/update binding in external_id_table */
558 prefix_id
.family
= AF_INET
;
559 prefix_id
.prefixlen
= 32;
560 prefix_id
.u
.prefix4
.s_addr
= htonl (info
->id
);
561 node
= route_node_get (ospf6
->external_id_table
, &prefix_id
);
564 route
= ospf6_route_add (route
, ospf6
->external_table
);
565 route
->route_option
= info
;
567 if (IS_OSPF6_DEBUG_ASBR
)
569 inet_ntop (AF_INET
, &prefix_id
.u
.prefix4
, ibuf
, sizeof (ibuf
));
570 zlog_info ("Advertise as AS-External Id:%s", ibuf
);
573 route
->path
.origin
.id
= htonl (info
->id
);
574 ospf6_as_external_lsa_originate (route
);
576 /* Router-Bit (ASBR Flag) may have to be updated */
577 for (lnode
= listhead (ospf6
->area_list
); lnode
; nextnode (lnode
))
579 oa
= (struct ospf6_area
*) getdata (lnode
);
580 OSPF6_ROUTER_LSA_SCHEDULE (oa
);
585 ospf6_asbr_redistribute_remove (int type
, int ifindex
, struct prefix
*prefix
)
587 struct ospf6_route
*match
;
588 struct ospf6_external_info
*info
= NULL
;
589 struct route_node
*node
;
590 struct ospf6_lsa
*lsa
;
591 struct prefix prefix_id
;
592 char pbuf
[64], ibuf
[16];
594 struct ospf6_area
*oa
;
596 match
= ospf6_route_lookup (prefix
, ospf6
->external_table
);
599 if (IS_OSPF6_DEBUG_ASBR
)
601 prefix2str (prefix
, pbuf
, sizeof (pbuf
));
602 zlog_info ("No such route %s to withdraw", pbuf
);
607 info
= match
->route_option
;
610 if (info
->type
!= type
)
612 if (IS_OSPF6_DEBUG_ASBR
)
614 prefix2str (prefix
, pbuf
, sizeof (pbuf
));
615 zlog_info ("Original protocol mismatch: %s", pbuf
);
620 if (IS_OSPF6_DEBUG_ASBR
)
622 prefix2str (prefix
, pbuf
, sizeof (pbuf
));
623 inet_ntop (AF_INET
, &prefix_id
.u
.prefix4
, ibuf
, sizeof (ibuf
));
624 zlog_info ("Withdraw %s (AS-External Id:%s)", pbuf
, ibuf
);
627 lsa
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL
),
628 htonl (info
->id
), ospf6
->router_id
, ospf6
->lsdb
);
630 ospf6_lsa_purge (lsa
);
632 /* remove binding in external_id_table */
633 prefix_id
.family
= AF_INET
;
634 prefix_id
.prefixlen
= 32;
635 prefix_id
.u
.prefix4
.s_addr
= htonl (info
->id
);
636 node
= route_node_lookup (ospf6
->external_id_table
, &prefix_id
);
639 route_unlock_node (node
);
641 ospf6_route_remove (match
, ospf6
->external_table
);
642 XFREE (MTYPE_OSPF6_EXTERNAL_INFO
, info
);
644 /* Router-Bit (ASBR Flag) may have to be updated */
645 for (lnode
= listhead (ospf6
->area_list
); lnode
; nextnode (lnode
))
647 oa
= (struct ospf6_area
*) getdata (lnode
);
648 OSPF6_ROUTER_LSA_SCHEDULE (oa
);
652 DEFUN (ospf6_redistribute
,
653 ospf6_redistribute_cmd
,
654 "redistribute (static|kernel|connected|ripng|bgp)",
665 if (strncmp (argv
[0], "sta", 3) == 0)
666 type
= ZEBRA_ROUTE_STATIC
;
667 else if (strncmp (argv
[0], "ker", 3) == 0)
668 type
= ZEBRA_ROUTE_KERNEL
;
669 else if (strncmp (argv
[0], "con", 3) == 0)
670 type
= ZEBRA_ROUTE_CONNECT
;
671 else if (strncmp (argv
[0], "rip", 3) == 0)
672 type
= ZEBRA_ROUTE_RIPNG
;
673 else if (strncmp (argv
[0], "bgp", 3) == 0)
674 type
= ZEBRA_ROUTE_BGP
;
676 ospf6_asbr_redistribute_unset (type
);
677 ospf6_asbr_routemap_unset (type
);
678 ospf6_asbr_redistribute_set (type
);
682 DEFUN (ospf6_redistribute_routemap
,
683 ospf6_redistribute_routemap_cmd
,
684 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
691 "Route map reference\n"
697 if (strncmp (argv
[0], "sta", 3) == 0)
698 type
= ZEBRA_ROUTE_STATIC
;
699 else if (strncmp (argv
[0], "ker", 3) == 0)
700 type
= ZEBRA_ROUTE_KERNEL
;
701 else if (strncmp (argv
[0], "con", 3) == 0)
702 type
= ZEBRA_ROUTE_CONNECT
;
703 else if (strncmp (argv
[0], "rip", 3) == 0)
704 type
= ZEBRA_ROUTE_RIPNG
;
705 else if (strncmp (argv
[0], "bgp", 3) == 0)
706 type
= ZEBRA_ROUTE_BGP
;
708 ospf6_asbr_redistribute_unset (type
);
709 ospf6_asbr_routemap_set (type
, argv
[1]);
710 ospf6_asbr_redistribute_set (type
);
714 DEFUN (no_ospf6_redistribute
,
715 no_ospf6_redistribute_cmd
,
716 "no redistribute (static|kernel|connected|ripng|bgp)",
728 if (strncmp (argv
[0], "sta", 3) == 0)
729 type
= ZEBRA_ROUTE_STATIC
;
730 else if (strncmp (argv
[0], "ker", 3) == 0)
731 type
= ZEBRA_ROUTE_KERNEL
;
732 else if (strncmp (argv
[0], "con", 3) == 0)
733 type
= ZEBRA_ROUTE_CONNECT
;
734 else if (strncmp (argv
[0], "rip", 3) == 0)
735 type
= ZEBRA_ROUTE_RIPNG
;
736 else if (strncmp (argv
[0], "bgp", 3) == 0)
737 type
= ZEBRA_ROUTE_BGP
;
739 ospf6_asbr_redistribute_unset (type
);
740 ospf6_asbr_routemap_unset (type
);
746 ospf6_redistribute_config_write (struct vty
*vty
)
750 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++)
752 if (type
== ZEBRA_ROUTE_OSPF6
)
754 if (! ospf6_zebra_is_redistribute (type
))
757 if (ospf6
->rmap
[type
].name
)
758 vty_out (vty
, " redistribute %s route-map %s%s",
759 ZROUTE_NAME (type
), ospf6
->rmap
[type
].name
, VNL
);
761 vty_out (vty
, " redistribute %s%s",
762 ZROUTE_NAME (type
), VNL
);
769 ospf6_redistribute_show_config (struct vty
*vty
)
772 int nroute
[ZEBRA_ROUTE_MAX
];
774 struct ospf6_route
*route
;
775 struct ospf6_external_info
*info
;
778 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++)
780 for (route
= ospf6_route_head (ospf6
->external_table
); route
;
781 route
= ospf6_route_next (route
))
783 info
= route
->route_option
;
784 nroute
[info
->type
]++;
788 vty_out (vty
, "Redistributing External Routes from:%s", VNL
);
789 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++)
791 if (type
== ZEBRA_ROUTE_OSPF6
)
793 if (! ospf6_zebra_is_redistribute (type
))
796 if (ospf6
->rmap
[type
].name
)
797 vty_out (vty
, " %d: %s with route-map \"%s\"%s%s", nroute
[type
],
798 ZROUTE_NAME (type
), ospf6
->rmap
[type
].name
,
799 (ospf6
->rmap
[type
].map
? "" : " (not found !)"),
802 vty_out (vty
, " %d: %s%s", nroute
[type
],
803 ZROUTE_NAME (type
), VNL
);
805 vty_out (vty
, "Total %d routes%s", total
, VNL
);
810 /* Routemap Functions */
812 ospf6_routemap_rule_match_address_prefixlist (void *rule
,
813 struct prefix
*prefix
,
814 route_map_object_t type
,
817 struct prefix_list
*plist
;
819 if (type
!= RMAP_OSPF6
)
822 plist
= prefix_list_lookup (AFI_IP6
, (char *) rule
);
826 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
827 RMAP_NOMATCH
: RMAP_MATCH
);
831 ospf6_routemap_rule_match_address_prefixlist_compile (char *arg
)
833 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
837 ospf6_routemap_rule_match_address_prefixlist_free (void *rule
)
839 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
842 struct route_map_rule_cmd
843 ospf6_routemap_rule_match_address_prefixlist_cmd
=
845 "ipv6 address prefix-list",
846 ospf6_routemap_rule_match_address_prefixlist
,
847 ospf6_routemap_rule_match_address_prefixlist_compile
,
848 ospf6_routemap_rule_match_address_prefixlist_free
,
852 ospf6_routemap_rule_set_metric_type (void *rule
, struct prefix
*prefix
,
853 route_map_object_t type
, void *object
)
855 char *metric_type
= rule
;
856 struct ospf6_route
*route
= object
;
858 if (type
!= RMAP_OSPF6
)
861 if (strcmp (metric_type
, "type-2") == 0)
862 route
->path
.metric_type
= 2;
864 route
->path
.metric_type
= 1;
870 ospf6_routemap_rule_set_metric_type_compile (char *arg
)
872 if (strcmp (arg
, "type-2") && strcmp (arg
, "type-1"))
874 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
878 ospf6_routemap_rule_set_metric_type_free (void *rule
)
880 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
883 struct route_map_rule_cmd
884 ospf6_routemap_rule_set_metric_type_cmd
=
887 ospf6_routemap_rule_set_metric_type
,
888 ospf6_routemap_rule_set_metric_type_compile
,
889 ospf6_routemap_rule_set_metric_type_free
,
893 ospf6_routemap_rule_set_metric (void *rule
, struct prefix
*prefix
,
894 route_map_object_t type
, void *object
)
897 struct ospf6_route
*route
= object
;
899 if (type
!= RMAP_OSPF6
)
902 route
->path
.cost
= atoi (metric
);
907 ospf6_routemap_rule_set_metric_compile (char *arg
)
911 metric
= strtoul (arg
, &endp
, 0);
912 if (metric
> LS_INFINITY
|| *endp
!= '\0')
914 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
918 ospf6_routemap_rule_set_metric_free (void *rule
)
920 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
923 struct route_map_rule_cmd
924 ospf6_routemap_rule_set_metric_cmd
=
927 ospf6_routemap_rule_set_metric
,
928 ospf6_routemap_rule_set_metric_compile
,
929 ospf6_routemap_rule_set_metric_free
,
933 ospf6_routemap_rule_set_forwarding (void *rule
, struct prefix
*prefix
,
934 route_map_object_t type
, void *object
)
936 char *forwarding
= rule
;
937 struct ospf6_route
*route
= object
;
938 struct ospf6_external_info
*info
= route
->route_option
;
940 if (type
!= RMAP_OSPF6
)
943 if (inet_pton (AF_INET6
, forwarding
, &info
->forwarding
) != 1)
945 memset (&info
->forwarding
, 0, sizeof (struct in6_addr
));
953 ospf6_routemap_rule_set_forwarding_compile (char *arg
)
956 if (inet_pton (AF_INET6
, arg
, &a
) != 1)
958 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
962 ospf6_routemap_rule_set_forwarding_free (void *rule
)
964 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
967 struct route_map_rule_cmd
968 ospf6_routemap_rule_set_forwarding_cmd
=
970 "forwarding-address",
971 ospf6_routemap_rule_set_forwarding
,
972 ospf6_routemap_rule_set_forwarding_compile
,
973 ospf6_routemap_rule_set_forwarding_free
,
977 route_map_command_status (struct vty
*vty
, int ret
)
984 case RMAP_RULE_MISSING
:
985 vty_out (vty
, "Can't find rule.%s", VNL
);
987 case RMAP_COMPILE_ERROR
:
988 vty_out (vty
, "Argument is malformed.%s", VNL
);
991 vty_out (vty
, "route-map add set failed.%s", VNL
);
997 /* add "match address" */
998 DEFUN (ospf6_routemap_match_address_prefixlist
,
999 ospf6_routemap_match_address_prefixlist_cmd
,
1000 "match ipv6 address prefix-list WORD",
1003 "Match address of route\n"
1004 "Match entries of prefix-lists\n"
1005 "IPv6 prefix-list name\n")
1007 int ret
= route_map_add_match ((struct route_map_index
*) vty
->index
,
1008 "ipv6 address prefix-list", argv
[0]);
1009 return route_map_command_status (vty
, ret
);
1012 /* delete "match address" */
1013 DEFUN (ospf6_routemap_no_match_address_prefixlist
,
1014 ospf6_routemap_no_match_address_prefixlist_cmd
,
1015 "no match ipv6 address prefix-list WORD",
1019 "Match address of route\n"
1020 "Match entries of prefix-lists\n"
1021 "IPv6 prefix-list name\n")
1023 int ret
= route_map_delete_match ((struct route_map_index
*) vty
->index
,
1024 "ipv6 address prefix-list", argv
[0]);
1025 return route_map_command_status (vty
, ret
);
1028 /* add "set metric-type" */
1029 DEFUN (ospf6_routemap_set_metric_type
,
1030 ospf6_routemap_set_metric_type_cmd
,
1031 "set metric-type (type-1|type-2)",
1034 "OSPF6 external type 1 metric\n"
1035 "OSPF6 external type 2 metric\n")
1037 int ret
= route_map_add_set ((struct route_map_index
*) vty
->index
,
1038 "metric-type", argv
[0]);
1039 return route_map_command_status (vty
, ret
);
1042 /* delete "set metric-type" */
1043 DEFUN (ospf6_routemap_no_set_metric_type
,
1044 ospf6_routemap_no_set_metric_type_cmd
,
1045 "no set metric-type (type-1|type-2)",
1049 "OSPF6 external type 1 metric\n"
1050 "OSPF6 external type 2 metric\n")
1052 int ret
= route_map_delete_set ((struct route_map_index
*) vty
->index
,
1053 "metric-type", argv
[0]);
1054 return route_map_command_status (vty
, ret
);
1057 /* add "set metric" */
1060 "set metric <0-4294967295>",
1065 int ret
= route_map_add_set ((struct route_map_index
*) vty
->index
,
1067 return route_map_command_status (vty
, ret
);
1070 /* delete "set metric" */
1071 DEFUN (no_set_metric
,
1073 "no set metric <0-4294967295>",
1079 int ret
= route_map_delete_set ((struct route_map_index
*) vty
->index
,
1081 return route_map_command_status (vty
, ret
);
1084 /* add "set forwarding-address" */
1085 DEFUN (ospf6_routemap_set_forwarding
,
1086 ospf6_routemap_set_forwarding_cmd
,
1087 "set forwarding-address X:X::X:X",
1089 "Forwarding Address\n"
1092 int ret
= route_map_add_set ((struct route_map_index
*) vty
->index
,
1093 "forwarding-address", argv
[0]);
1094 return route_map_command_status (vty
, ret
);
1097 /* delete "set forwarding-address" */
1098 DEFUN (ospf6_routemap_no_set_forwarding
,
1099 ospf6_routemap_no_set_forwarding_cmd
,
1100 "no set forwarding-address X:X::X:X",
1103 "Forwarding Address\n"
1106 int ret
= route_map_delete_set ((struct route_map_index
*) vty
->index
,
1107 "forwarding-address", argv
[0]);
1108 return route_map_command_status (vty
, ret
);
1112 ospf6_routemap_init ()
1115 route_map_init_vty ();
1116 route_map_add_hook (ospf6_asbr_routemap_update
);
1117 route_map_delete_hook (ospf6_asbr_routemap_update
);
1119 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd
);
1120 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd
);
1121 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd
);
1122 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd
);
1124 /* Match address prefix-list */
1125 install_element (RMAP_NODE
, &ospf6_routemap_match_address_prefixlist_cmd
);
1126 install_element (RMAP_NODE
, &ospf6_routemap_no_match_address_prefixlist_cmd
);
1128 /* ASE Metric Type (e.g. Type-1/Type-2) */
1129 install_element (RMAP_NODE
, &ospf6_routemap_set_metric_type_cmd
);
1130 install_element (RMAP_NODE
, &ospf6_routemap_no_set_metric_type_cmd
);
1133 install_element (RMAP_NODE
, &set_metric_cmd
);
1134 install_element (RMAP_NODE
, &no_set_metric_cmd
);
1137 install_element (RMAP_NODE
, &ospf6_routemap_set_forwarding_cmd
);
1138 install_element (RMAP_NODE
, &ospf6_routemap_no_set_forwarding_cmd
);
1142 /* Display functions */
1144 ospf6_as_external_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
1146 struct ospf6_as_external_lsa
*external
;
1148 struct in6_addr in6
, *forwarding
;
1150 assert (lsa
->header
);
1151 external
= (struct ospf6_as_external_lsa
*)
1152 OSPF6_LSA_HEADER_END (lsa
->header
);
1155 snprintf (buf
, sizeof (buf
), "%c%c%c",
1156 (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_E
) ? 'E' : '-'),
1157 (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_F
) ? 'F' : '-'),
1158 (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_T
) ? 'T' : '-'));
1160 vty_out (vty
, " Bits: %s%s", buf
, VNL
);
1161 vty_out (vty
, " Metric: %5lu%s", (u_long
) OSPF6_ASBR_METRIC (external
),
1164 ospf6_prefix_options_printbuf (external
->prefix
.prefix_options
,
1166 vty_out (vty
, " Prefix Options: %s%s", buf
,
1169 vty_out (vty
, " Referenced LSType: %d%s",
1170 ntohs (external
->prefix
.prefix_refer_lstype
),
1173 ospf6_prefix_in6_addr (&in6
, &external
->prefix
);
1174 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
1175 vty_out (vty
, " Prefix: %s/%d%s", buf
,
1176 external
->prefix
.prefix_length
, VNL
);
1178 /* Forwarding-Address */
1179 if (CHECK_FLAG (external
->bits_metric
, OSPF6_ASBR_BIT_F
))
1181 forwarding
= (struct in6_addr
*)
1182 ((caddr_t
) external
+ sizeof (struct ospf6_as_external_lsa
) +
1183 OSPF6_PREFIX_SPACE (external
->prefix
.prefix_length
));
1184 inet_ntop (AF_INET6
, forwarding
, buf
, sizeof (buf
));
1185 vty_out (vty
, " Forwarding-Address: %s%s", buf
, VNL
);
1192 ospf6_asbr_external_route_show (struct vty
*vty
, struct ospf6_route
*route
)
1194 struct ospf6_external_info
*info
= route
->route_option
;
1195 char prefix
[64], id
[16], forwarding
[64];
1198 prefix2str (&route
->prefix
, prefix
, sizeof (prefix
));
1199 tmp_id
= ntohl (info
->id
);
1200 inet_ntop (AF_INET
, &tmp_id
, id
, sizeof (id
));
1201 if (! IN6_IS_ADDR_UNSPECIFIED (&info
->forwarding
))
1202 inet_ntop (AF_INET6
, &info
->forwarding
, forwarding
, sizeof (forwarding
));
1204 snprintf (forwarding
, sizeof (forwarding
), ":: (ifindex %d)",
1205 route
->nexthop
[0].ifindex
);
1207 vty_out (vty
, "%s %-32s %-15s type-%d %5lu %s%s",
1208 ZROUTE_ABNAME (info
->type
),
1209 prefix
, id
, route
->path
.metric_type
,
1210 (u_long
) (route
->path
.metric_type
== 2 ?
1211 route
->path
.cost_e2
: route
->path
.cost
),
1215 DEFUN (show_ipv6_ospf6_redistribute
,
1216 show_ipv6_ospf6_redistribute_cmd
,
1217 "show ipv6 ospf6 redistribute",
1221 "redistributing External information\n"
1224 struct ospf6_route
*route
;
1226 ospf6_redistribute_show_config (vty
);
1228 for (route
= ospf6_route_head (ospf6
->external_table
); route
;
1229 route
= ospf6_route_next (route
))
1230 ospf6_asbr_external_route_show (vty
, route
);
1235 struct ospf6_lsa_handler as_external_handler
=
1237 OSPF6_LSTYPE_AS_EXTERNAL
,
1239 ospf6_as_external_lsa_show
1245 ospf6_routemap_init ();
1247 ospf6_install_lsa_handler (&as_external_handler
);
1249 install_element (VIEW_NODE
, &show_ipv6_ospf6_redistribute_cmd
);
1250 install_element (ENABLE_NODE
, &show_ipv6_ospf6_redistribute_cmd
);
1252 install_element (OSPF6_NODE
, &ospf6_redistribute_cmd
);
1253 install_element (OSPF6_NODE
, &ospf6_redistribute_routemap_cmd
);
1254 install_element (OSPF6_NODE
, &no_ospf6_redistribute_cmd
);
1258 DEFUN (debug_ospf6_asbr
,
1259 debug_ospf6_asbr_cmd
,
1263 "Debug OSPFv3 ASBR function\n"
1266 OSPF6_DEBUG_ASBR_ON ();
1270 DEFUN (no_debug_ospf6_asbr
,
1271 no_debug_ospf6_asbr_cmd
,
1272 "no debug ospf6 asbr",
1276 "Debug OSPFv3 ASBR function\n"
1279 OSPF6_DEBUG_ASBR_OFF ();
1284 config_write_ospf6_debug_asbr (struct vty
*vty
)
1286 if (IS_OSPF6_DEBUG_ASBR
)
1287 vty_out (vty
, "debug ospf6 asbr%s", VNL
);
1292 install_element_ospf6_debug_asbr ()
1294 install_element (ENABLE_NODE
, &debug_ospf6_asbr_cmd
);
1295 install_element (ENABLE_NODE
, &no_debug_ospf6_asbr_cmd
);
1296 install_element (CONFIG_NODE
, &debug_ospf6_asbr_cmd
);
1297 install_element (CONFIG_NODE
, &no_debug_ospf6_asbr_cmd
);