usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / zebra / ospf6d / ospf6_asbr.c
blob49bba799c280e906ef712b201511a90ad8343429
1 /*
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
9 * later version.
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.
22 #include <zebra.h>
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"
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"
49 #include "ospf6d.h"
51 unsigned char conf_debug_ospf6_asbr = 0;
53 char *zroute_name[] =
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 */
68 void
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;
76 char buf[64];
77 caddr_t p;
79 /* find previous LSA */
80 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
81 route->path.origin.id, ospf6->router_id,
82 ospf6->lsdb);
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);
90 /* prepare buffer */
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));
95 p = (caddr_t)
96 ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));
98 /* Fill AS-External-LSA */
99 /* Metric type */
100 if (route->path.metric_type == 2)
101 SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
102 else
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);
108 else
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);
114 /* Set metric */
115 OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
117 /* prefixlen */
118 as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
120 /* PrefixOptions */
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);
126 /* set Prefix */
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))
142 /* xxx */
145 /* Fill LSA Header */
146 lsa_header->age = 0;
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;
150 lsa_header->seqnum =
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);
155 /* LSA checksum */
156 ospf6_lsa_checksum (lsa_header);
158 /* create LSA */
159 lsa = ospf6_lsa_create (lsa_header);
161 /* Originate */
162 ospf6_lsa_originate_process (lsa, ospf6);
166 void
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;
172 char buf[64];
173 int i;
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");
185 return;
188 if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
190 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
191 zlog_info ("Ignore LSA with LSInfinity Metric");
192 return;
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);
205 return;
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);
227 else
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);
247 void
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;
253 char buf[64];
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");
265 return;
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);
274 if (route == NULL)
276 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
278 prefix2str (&prefix, buf, sizeof (buf));
279 zlog_info ("AS-External route %s not found", buf);
281 return;
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)
289 continue;
290 if (route->path.origin.type != lsa->header->type)
291 continue;
292 if (route->path.origin.id != lsa->header->id)
293 continue;
294 if (route->path.origin.adv_router != lsa->header->adv_router)
295 continue;
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);
306 void
307 ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
309 char buf[64];
310 struct ospf6_lsa *lsa;
311 u_int16_t type;
312 u_int32_t router;
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);
336 void
337 ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
339 char buf[64];
340 struct ospf6_lsa *lsa;
341 u_int16_t type;
342 u_int32_t router;
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 */
367 void
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);
376 void
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;
385 void
386 ospf6_asbr_routemap_update (char *mapname)
388 int type;
390 if (ospf6 == NULL)
391 return;
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);
398 else
399 ospf6->rmap[type].map = NULL;
404 ospf6_asbr_is_asbr (struct ospf6 *o)
406 return o->external_table->count;
409 void
410 ospf6_asbr_redistribute_set (int type)
412 ospf6_zebra_redistribute (type);
415 void
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)
428 continue;
430 ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
431 &route->prefix);
435 void
436 ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
437 u_int nexthop_num, struct in6_addr *nexthop)
439 int ret;
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];
447 listnode lnode;
448 struct ospf6_area *oa;
450 if (! ospf6_zebra_is_redistribute (type))
451 return;
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);
468 return;
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);
485 return;
489 match = ospf6_route_lookup (prefix, ospf6->external_table);
490 if (match)
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));
506 info->type = type;
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);
516 node->info = match;
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);
526 return;
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));
552 info->type = type;
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);
562 node->info = route;
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);
584 void
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];
593 listnode lnode;
594 struct ospf6_area *oa;
596 match = ospf6_route_lookup (prefix, ospf6->external_table);
597 if (match == NULL)
599 if (IS_OSPF6_DEBUG_ASBR)
601 prefix2str (prefix, pbuf, sizeof (pbuf));
602 zlog_info ("No such route %s to withdraw", pbuf);
604 return;
607 info = match->route_option;
608 assert (info);
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);
617 return;
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);
629 if (lsa)
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);
637 assert (node);
638 node->info = NULL;
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)",
655 "Redistribute\n"
656 "Static route\n"
657 "Kernel route\n"
658 "Connected route\n"
659 "RIPng route\n"
660 "BGP route\n"
663 int type = 0;
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);
679 return CMD_SUCCESS;
682 DEFUN (ospf6_redistribute_routemap,
683 ospf6_redistribute_routemap_cmd,
684 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
685 "Redistribute\n"
686 "Static routes\n"
687 "Kernel route\n"
688 "Connected route\n"
689 "RIPng route\n"
690 "BGP route\n"
691 "Route map reference\n"
692 "Route map name\n"
695 int type = 0;
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);
711 return CMD_SUCCESS;
714 DEFUN (no_ospf6_redistribute,
715 no_ospf6_redistribute_cmd,
716 "no redistribute (static|kernel|connected|ripng|bgp)",
717 NO_STR
718 "Redistribute\n"
719 "Static route\n"
720 "Kernel route\n"
721 "Connected route\n"
722 "RIPng route\n"
723 "BGP route\n"
726 int type = 0;
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);
742 return CMD_SUCCESS;
746 ospf6_redistribute_config_write (struct vty *vty)
748 int type;
750 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
752 if (type == ZEBRA_ROUTE_OSPF6)
753 continue;
754 if (! ospf6_zebra_is_redistribute (type))
755 continue;
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);
760 else
761 vty_out (vty, " redistribute %s%s",
762 ZROUTE_NAME (type), VNL);
765 return 0;
768 void
769 ospf6_redistribute_show_config (struct vty *vty)
771 int type;
772 int nroute[ZEBRA_ROUTE_MAX];
773 int total;
774 struct ospf6_route *route;
775 struct ospf6_external_info *info;
777 total = 0;
778 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
779 nroute[type] = 0;
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]++;
785 total++;
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)
792 continue;
793 if (! ospf6_zebra_is_redistribute (type))
794 continue;
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 !)"),
800 VNL);
801 else
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 */
811 route_map_result_t
812 ospf6_routemap_rule_match_address_prefixlist (void *rule,
813 struct prefix *prefix,
814 route_map_object_t type,
815 void *object)
817 struct prefix_list *plist;
819 if (type != RMAP_OSPF6)
820 return RMAP_NOMATCH;
822 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
823 if (plist == NULL)
824 return RMAP_NOMATCH;
826 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
827 RMAP_NOMATCH : RMAP_MATCH);
830 void *
831 ospf6_routemap_rule_match_address_prefixlist_compile (char *arg)
833 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
836 void
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,
851 route_map_result_t
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)
859 return RMAP_OKAY;
861 if (strcmp (metric_type, "type-2") == 0)
862 route->path.metric_type = 2;
863 else
864 route->path.metric_type = 1;
866 return RMAP_OKAY;
869 void *
870 ospf6_routemap_rule_set_metric_type_compile (char *arg)
872 if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
873 return NULL;
874 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
877 void
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 =
886 "metric-type",
887 ospf6_routemap_rule_set_metric_type,
888 ospf6_routemap_rule_set_metric_type_compile,
889 ospf6_routemap_rule_set_metric_type_free,
892 route_map_result_t
893 ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
894 route_map_object_t type, void *object)
896 char *metric = rule;
897 struct ospf6_route *route = object;
899 if (type != RMAP_OSPF6)
900 return RMAP_OKAY;
902 route->path.cost = atoi (metric);
903 return RMAP_OKAY;
906 void *
907 ospf6_routemap_rule_set_metric_compile (char *arg)
909 u_int32_t metric;
910 char *endp;
911 metric = strtoul (arg, &endp, 0);
912 if (metric > LS_INFINITY || *endp != '\0')
913 return NULL;
914 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
917 void
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 =
926 "metric",
927 ospf6_routemap_rule_set_metric,
928 ospf6_routemap_rule_set_metric_compile,
929 ospf6_routemap_rule_set_metric_free,
932 route_map_result_t
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)
941 return RMAP_OKAY;
943 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
945 memset (&info->forwarding, 0, sizeof (struct in6_addr));
946 return RMAP_ERROR;
949 return RMAP_OKAY;
952 void *
953 ospf6_routemap_rule_set_forwarding_compile (char *arg)
955 struct in6_addr a;
956 if (inet_pton (AF_INET6, arg, &a) != 1)
957 return NULL;
958 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
961 void
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)
979 if (! ret)
980 return CMD_SUCCESS;
982 switch (ret)
984 case RMAP_RULE_MISSING:
985 vty_out (vty, "Can't find rule.%s", VNL);
986 break;
987 case RMAP_COMPILE_ERROR:
988 vty_out (vty, "Argument is malformed.%s", VNL);
989 break;
990 default:
991 vty_out (vty, "route-map add set failed.%s", VNL);
992 break;
994 return CMD_WARNING;
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",
1001 "Match values\n"
1002 IPV6_STR
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",
1016 NO_STR
1017 "Match values\n"
1018 IPV6_STR
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)",
1032 "Set value\n"
1033 "Type of metric\n"
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)",
1046 NO_STR
1047 "Set value\n"
1048 "Type of metric\n"
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" */
1058 DEFUN (set_metric,
1059 set_metric_cmd,
1060 "set metric <0-4294967295>",
1061 "Set value\n"
1062 "Metric value\n"
1063 "Metric value\n")
1065 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1066 "metric", argv[0]);
1067 return route_map_command_status (vty, ret);
1070 /* delete "set metric" */
1071 DEFUN (no_set_metric,
1072 no_set_metric_cmd,
1073 "no set metric <0-4294967295>",
1074 NO_STR
1075 "Set value\n"
1076 "Metric\n"
1077 "METRIC value\n")
1079 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1080 "metric", argv[0]);
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",
1088 "Set value\n"
1089 "Forwarding Address\n"
1090 "IPv6 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",
1101 NO_STR
1102 "Set value\n"
1103 "Forwarding Address\n"
1104 "IPv6 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);
1111 void
1112 ospf6_routemap_init ()
1114 route_map_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);
1132 /* ASE Metric */
1133 install_element (RMAP_NODE, &set_metric_cmd);
1134 install_element (RMAP_NODE, &no_set_metric_cmd);
1136 /* ASE Metric */
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;
1147 char buf[64];
1148 struct in6_addr in6, *forwarding;
1150 assert (lsa->header);
1151 external = (struct ospf6_as_external_lsa *)
1152 OSPF6_LSA_HEADER_END (lsa->header);
1154 /* bits */
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),
1162 VNL);
1164 ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1165 buf, sizeof (buf));
1166 vty_out (vty, " Prefix Options: %s%s", buf,
1167 VNL);
1169 vty_out (vty, " Referenced LSType: %d%s",
1170 ntohs (external->prefix.prefix_refer_lstype),
1171 VNL);
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);
1188 return 0;
1191 void
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];
1196 u_int32_t tmp_id;
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));
1203 else
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),
1212 forwarding, VNL);
1215 DEFUN (show_ipv6_ospf6_redistribute,
1216 show_ipv6_ospf6_redistribute_cmd,
1217 "show ipv6 ospf6 redistribute",
1218 SHOW_STR
1219 IP6_STR
1220 OSPF6_STR
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);
1232 return CMD_SUCCESS;
1235 struct ospf6_lsa_handler as_external_handler =
1237 OSPF6_LSTYPE_AS_EXTERNAL,
1238 "AS-External",
1239 ospf6_as_external_lsa_show
1242 void
1243 ospf6_asbr_init ()
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,
1260 "debug ospf6 asbr",
1261 DEBUG_STR
1262 OSPF6_STR
1263 "Debug OSPFv3 ASBR function\n"
1266 OSPF6_DEBUG_ASBR_ON ();
1267 return CMD_SUCCESS;
1270 DEFUN (no_debug_ospf6_asbr,
1271 no_debug_ospf6_asbr_cmd,
1272 "no debug ospf6 asbr",
1273 NO_STR
1274 DEBUG_STR
1275 OSPF6_STR
1276 "Debug OSPFv3 ASBR function\n"
1279 OSPF6_DEBUG_ASBR_OFF ();
1280 return CMD_SUCCESS;
1284 config_write_ospf6_debug_asbr (struct vty *vty)
1286 if (IS_OSPF6_DEBUG_ASBR)
1287 vty_out (vty, "debug ospf6 asbr%s", VNL);
1288 return 0;
1291 void
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);