blob: 18f7cc26e8274dcf9e0d5b1e6e87aa15d45f5922 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
hasso508e53e2004-05-18 18:57:06 +00002 * Copyright (C) 2003 Yasuhiro Ohara
paul718e3742002-12-13 20:15:29 +00003 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "log.h"
25#include "memory.h"
26#include "prefix.h"
27#include "command.h"
28#include "vty.h"
29#include "routemap.h"
30#include "table.h"
31#include "plist.h"
32#include "thread.h"
hasso508e53e2004-05-18 18:57:06 +000033#include "linklist.h"
paul718e3742002-12-13 20:15:29 +000034
paul718e3742002-12-13 20:15:29 +000035#include "ospf6_proto.h"
hasso508e53e2004-05-18 18:57:06 +000036#include "ospf6_lsa.h"
37#include "ospf6_lsdb.h"
38#include "ospf6_route.h"
39#include "ospf6_zebra.h"
40#include "ospf6_top.h"
41#include "ospf6_area.h"
42#include "ospf6_asbr.h"
43#include "ospf6_intra.h"
hasso049207c2004-08-04 20:02:13 +000044#include "ospf6d.h"
paul718e3742002-12-13 20:15:29 +000045
hasso508e53e2004-05-18 18:57:06 +000046unsigned char conf_debug_ospf6_asbr = 0;
paul718e3742002-12-13 20:15:29 +000047
hasso508e53e2004-05-18 18:57:06 +000048char *zroute_name[] =
49{ "system", "kernel", "connected", "static",
hasso3b4cd3a2004-05-18 19:28:32 +000050 "rip", "ripng", "ospf", "ospf6", "isis", "bgp", "unknown" };
hasso508e53e2004-05-18 18:57:06 +000051
52char *zroute_abname[] =
hasso3b4cd3a2004-05-18 19:28:32 +000053{ "X", "K", "C", "S", "R", "R", "O", "O", "I", "B", "?" };
hasso508e53e2004-05-18 18:57:06 +000054
55#define ZROUTE_NAME(x) \
56 (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? zroute_name[(x)] : \
57 zroute_name[ZEBRA_ROUTE_MAX])
58#define ZROUTE_ABNAME(x) \
59 (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? zroute_abname[(x)] : \
60 zroute_abname[ZEBRA_ROUTE_MAX])
61
62/* AS External LSA origination */
63void
64ospf6_as_external_lsa_originate_sub (struct ospf6_route *route, int force)
paul718e3742002-12-13 20:15:29 +000065{
hasso508e53e2004-05-18 18:57:06 +000066 char buffer[OSPF6_MAX_LSASIZE];
67 struct ospf6_lsa_header *lsa_header;
68 struct ospf6_lsa *old, *lsa;
paul718e3742002-12-13 20:15:29 +000069
hasso508e53e2004-05-18 18:57:06 +000070 struct ospf6_external_info *info = route->route_option;
71 struct ospf6_as_external_lsa *as_external_lsa;
72 char buf[64];
73 caddr_t p;
paul718e3742002-12-13 20:15:29 +000074
hasso508e53e2004-05-18 18:57:06 +000075 /* find previous LSA */
76 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
77 htonl (info->id), ospf6->router_id,
78 ospf6->lsdb);
79
80 if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
81 {
82 prefix2str (&route->prefix, buf, sizeof (buf));
83 zlog_info ("Originate AS-External-LSA for %s", buf);
84 }
85
86 /* prepare buffer */
87 memset (buffer, 0, sizeof (buffer));
88 lsa_header = (struct ospf6_lsa_header *) buffer;
89 as_external_lsa = (struct ospf6_as_external_lsa *)
90 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
91 p = (caddr_t)
92 ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));
93
94 /* Fill AS-External-LSA */
95 /* Metric type */
96 if (route->path.metric_type == 2)
97 SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
98 else
99 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
100
101 /* forwarding address */
102 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
103 SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
104 else
105 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
106
107 /* external route tag */
108 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
109
110 /* Set metric */
111 OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
112
113 /* prefixlen */
114 as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
115
116 /* PrefixOptions */
117 as_external_lsa->prefix.prefix_options = route->path.prefix_options;
118
119 /* don't use refer LS-type */
120 as_external_lsa->prefix.prefix_refer_lstype = htons (0);
121
122 /* set Prefix */
123 memcpy (p, &route->prefix.u.prefix6,
124 OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
125 ospf6_prefix_apply_mask (&as_external_lsa->prefix);
126 p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
127
128 /* Forwarding address */
129 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
130 {
131 memcpy (p, &info->forwarding, sizeof (struct in6_addr));
132 p += sizeof (struct in6_addr);
133 }
134
135 /* External Route Tag */
136 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
137 {
138 /* xxx */
139 }
140
141 /* Fill LSA Header */
142 lsa_header->age = 0;
143 lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
144 lsa_header->id = htonl (info->id);
145 lsa_header->adv_router = ospf6->router_id;
146 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000147 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
148 lsa_header->adv_router, ospf6->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000149 lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
150
151 /* LSA checksum */
152 ospf6_lsa_checksum (lsa_header);
153
154 /* create LSA */
155 lsa = ospf6_lsa_create (lsa_header);
156 lsa->scope = ospf6;
157 if (force)
158 SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
159
160 /* Originate */
161 ospf6_lsa_originate (lsa);
162}
163
164int
165ospf6_as_external_lsa_reoriginate (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +0000166{
hasso508e53e2004-05-18 18:57:06 +0000167 struct prefix prefix_id;
168 struct route_node *node;
169 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000170
hasso508e53e2004-05-18 18:57:06 +0000171 /* create/update binding in external_id_table */
172 prefix_id.family = AF_INET;
173 prefix_id.prefixlen = 32;
174 prefix_id.u.prefix4.s_addr = lsa->header->id;
175 node = route_node_get (ospf6->external_id_table, &prefix_id);
176 route = node->info;
paul718e3742002-12-13 20:15:29 +0000177
hasso508e53e2004-05-18 18:57:06 +0000178 if (route)
179 ospf6_as_external_lsa_originate_sub (route, 1);
180 else
181 ospf6_lsa_premature_aging (lsa);
paul718e3742002-12-13 20:15:29 +0000182
hasso508e53e2004-05-18 18:57:06 +0000183 return 0;
184}
185
186
187
188void
189ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
190{
191 struct ospf6_as_external_lsa *external;
192 struct prefix asbr_id;
193 struct ospf6_route *asbr_entry, *route;
194 char buf[64];
195 int i;
196
197 external = (struct ospf6_as_external_lsa *)
198 OSPF6_LSA_HEADER_END (lsa->header);
199
200 if (IS_OSPF6_DEBUG_ASBR)
201 zlog_info ("Calculate AS-External route for %s", lsa->name);
202
203 if (lsa->header->adv_router == ospf6->router_id)
204 {
205 if (IS_OSPF6_DEBUG_ASBR)
206 zlog_info ("Ignore self-originated AS-External-LSA");
207 return;
208 }
209
210 if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
211 {
212 if (IS_OSPF6_DEBUG_ASBR)
213 zlog_info ("Ignore LSA with LSInfinity Metric");
214 return;
215 }
216
217 asbr_id.family = AF_INET;
218 asbr_id.prefixlen = 32;
219 asbr_id.u.prefix4.s_addr = lsa->header->adv_router;
220 asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->asbr_table);
221
222 if (asbr_entry == NULL)
223 {
224 if (IS_OSPF6_DEBUG_ASBR)
225 {
226 prefix2str (&asbr_id, buf, sizeof (buf));
227 zlog_info ("ASBR entry not found: %s", buf);
228 }
229 return;
230 }
231
232 route = ospf6_route_create ();
233 route->type = OSPF6_DEST_TYPE_NETWORK;
234 route->prefix.family = AF_INET6;
235 route->prefix.prefixlen = external->prefix.prefix_length;
236 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
237
238 route->path.area_id = asbr_entry->path.area_id;
239 route->path.origin.type = lsa->header->type;
240 route->path.origin.id = lsa->header->id;
241 route->path.origin.adv_router = lsa->header->adv_router;
242
243 route->path.prefix_options = external->prefix.prefix_options;
244 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
245 {
246 route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
247 route->path.metric_type = 2;
248 route->path.cost = asbr_entry->path.cost;
249 route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
250 }
251 else
252 {
253 route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
254 route->path.metric_type = 1;
255 route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
256 route->path.cost_e2 = 0;
257 }
258
259 for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
260 ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
261
262 if (IS_OSPF6_DEBUG_ASBR)
263 {
264 prefix2str (&route->prefix, buf, sizeof (buf));
265 zlog_info ("AS-External route add: %s", buf);
266 }
267
268 ospf6_route_add (route, ospf6->route_table);
269}
270
271void
272ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
273{
274 struct ospf6_as_external_lsa *external;
275 struct prefix prefix;
276 struct ospf6_route *route;
277 char buf[64];
278
279 external = (struct ospf6_as_external_lsa *)
280 OSPF6_LSA_HEADER_END (lsa->header);
281
282 if (IS_OSPF6_DEBUG_ASBR)
283 zlog_info ("Withdraw AS-External route for %s", lsa->name);
284
285 if (lsa->header->adv_router == ospf6->router_id)
286 {
287 if (IS_OSPF6_DEBUG_ASBR)
288 zlog_info ("Ignore self-originated AS-External-LSA");
289 return;
290 }
291
292 memset (&prefix, 0, sizeof (struct prefix));
293 prefix.family = AF_INET6;
294 prefix.prefixlen = external->prefix.prefix_length;
295 ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
296
297 route = ospf6_route_lookup (&prefix, ospf6->route_table);
298 if (route == NULL)
299 {
300 if (IS_OSPF6_DEBUG_ASBR)
301 {
302 prefix2str (&prefix, buf, sizeof (buf));
303 zlog_info ("AS-External route %s not found", buf);
304 }
305 return;
306 }
307
308 for (ospf6_route_lock (route);
309 route && ospf6_route_is_prefix (&prefix, route);
310 route = ospf6_route_next (route))
311 {
312 if (route->type != OSPF6_DEST_TYPE_NETWORK)
313 continue;
314 if (route->path.origin.type != lsa->header->type)
315 continue;
316 if (route->path.origin.id != lsa->header->id)
317 continue;
318 if (route->path.origin.adv_router != lsa->header->adv_router)
319 continue;
320
321 if (IS_OSPF6_DEBUG_ASBR)
322 {
323 prefix2str (&route->prefix, buf, sizeof (buf));
324 zlog_info ("AS-External route remove: %s", buf);
325 }
326 ospf6_route_remove (route, ospf6->route_table);
327 }
328}
329
330void
331ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
332{
333 char buf[64];
334 struct ospf6_lsa *lsa;
335 u_int16_t type;
336 u_int32_t router;
337
338 if (IS_OSPF6_DEBUG_ASBR)
339 {
340 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
341 zlog_info ("New ASBR %s found", buf);
342 }
343
344 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
345 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
346 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
347 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
348 {
349 if (! OSPF6_LSA_IS_MAXAGE (lsa))
350 ospf6_asbr_lsa_add (lsa);
351 }
352
353 if (IS_OSPF6_DEBUG_ASBR)
354 {
355 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
356 zlog_info ("Calculation for new ASBR %s done", buf);
357 }
358}
359
360void
361ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
362{
363 char buf[64];
364 struct ospf6_lsa *lsa;
365 u_int16_t type;
366 u_int32_t router;
367
368 if (IS_OSPF6_DEBUG_ASBR)
369 {
370 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
371 zlog_info ("ASBR %s disappeared", buf);
372 }
373
374 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
375 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
376 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
377 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
378 ospf6_asbr_lsa_remove (lsa);
379
380 if (IS_OSPF6_DEBUG_ASBR)
381 {
382 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
383 zlog_info ("Calculation for old ASBR %s done", buf);
384 }
385}
386
387
388
paul718e3742002-12-13 20:15:29 +0000389/* redistribute function */
hasso508e53e2004-05-18 18:57:06 +0000390
paul718e3742002-12-13 20:15:29 +0000391void
392ospf6_asbr_routemap_set (int type, char *mapname)
393{
hasso508e53e2004-05-18 18:57:06 +0000394 if (ospf6->rmap[type].name)
395 free (ospf6->rmap[type].name);
396 ospf6->rmap[type].name = strdup (mapname);
397 ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
paul718e3742002-12-13 20:15:29 +0000398}
399
400void
401ospf6_asbr_routemap_unset (int type)
402{
hasso508e53e2004-05-18 18:57:06 +0000403 if (ospf6->rmap[type].name)
404 free (ospf6->rmap[type].name);
405 ospf6->rmap[type].name = NULL;
406 ospf6->rmap[type].map = NULL;
paul718e3742002-12-13 20:15:29 +0000407}
408
409void
410ospf6_asbr_routemap_update ()
411{
hasso508e53e2004-05-18 18:57:06 +0000412 int type;
413
414 if (ospf6 == NULL)
415 return;
416
417 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000418 {
hasso508e53e2004-05-18 18:57:06 +0000419 if (ospf6->rmap[type].name)
420 ospf6->rmap[type].map =
421 route_map_lookup_by_name (ospf6->rmap[type].name);
paul718e3742002-12-13 20:15:29 +0000422 else
hasso508e53e2004-05-18 18:57:06 +0000423 ospf6->rmap[type].map = NULL;
424 }
425}
426
427int
428ospf6_asbr_is_asbr (struct ospf6 *o)
429{
430 return o->external_table->count;
431}
432
433void
434ospf6_asbr_redistribute_set (int type)
435{
436 ospf6_zebra_redistribute (type);
437}
438
439void
440ospf6_asbr_redistribute_unset (int type)
441{
442 struct ospf6_route *route;
443 struct ospf6_external_info *info;
444
445 ospf6_zebra_no_redistribute (type);
446
447 for (route = ospf6_route_head (ospf6->external_table); route;
448 route = ospf6_route_next (route))
449 {
450 info = route->route_option;
451 if (info->type != type)
452 continue;
453
454 ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
455 &route->prefix);
456 }
457}
458
459void
460ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
461 u_int nexthop_num, struct in6_addr *nexthop)
462{
463 int ret;
464 struct ospf6_route troute;
465 struct ospf6_external_info tinfo;
466 struct ospf6_route *route, *match;
467 struct ospf6_external_info *info;
468 struct prefix prefix_id;
469 struct route_node *node;
470 char pbuf[64], ibuf[16];
471 listnode lnode;
472 struct ospf6_area *oa;
473
474 if (! ospf6_zebra_is_redistribute (type))
475 return;
476
477 if (IS_OSPF6_DEBUG_ASBR)
478 {
479 prefix2str (prefix, pbuf, sizeof (pbuf));
480 zlog_info ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
481 }
482
483 /* if route-map was specified but not found, do not advertise */
484 if (ospf6->rmap[type].name)
485 {
486 if (ospf6->rmap[type].map == NULL)
487 ospf6_asbr_routemap_update ();
488 if (ospf6->rmap[type].map == NULL)
489 {
490 zlog_warn ("route-map \"%s\" not found, suppress redistributing",
491 ospf6->rmap[type].name);
492 return;
493 }
494 }
495
496 /* apply route-map */
497 if (ospf6->rmap[type].map)
498 {
499 memset (&troute, 0, sizeof (troute));
500 memset (&tinfo, 0, sizeof (tinfo));
501 troute.route_option = &tinfo;
502
503 ret = route_map_apply (ospf6->rmap[type].map, prefix,
504 RMAP_OSPF6, &troute);
505 if (ret != RMAP_MATCH)
506 {
507 if (IS_OSPF6_DEBUG_ASBR)
508 zlog_info ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
509 return;
510 }
511 }
512
513 match = ospf6_route_lookup (prefix, ospf6->external_table);
514 if (match)
515 {
516 info = match->route_option;
517
518 /* copy result of route-map */
519 if (ospf6->rmap[type].map)
520 {
521 if (troute.path.metric_type)
522 match->path.metric_type = troute.path.metric_type;
523 if (troute.path.cost)
524 match->path.cost = troute.path.cost;
525 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
526 memcpy (&info->forwarding, &tinfo.forwarding,
527 sizeof (struct in6_addr));
528 }
529
530 info->type = type;
531 match->nexthop[0].ifindex = ifindex;
532 if (nexthop_num && nexthop)
533 memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
534
535 /* create/update binding in external_id_table */
536 prefix_id.family = AF_INET;
537 prefix_id.prefixlen = 32;
538 prefix_id.u.prefix4.s_addr = htonl (info->id);
539 node = route_node_get (ospf6->external_id_table, &prefix_id);
540 node->info = match;
541
542 if (IS_OSPF6_DEBUG_ASBR)
543 {
544 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
545 zlog_info ("Advertise as AS-External Id:%s", ibuf);
546 }
547
548 ospf6_as_external_lsa_originate_sub (match, 0);
549 return;
550 }
551
552 /* create new entry */
553 route = ospf6_route_create ();
554 route->type = OSPF6_DEST_TYPE_NETWORK;
555 memcpy (&route->prefix, prefix, sizeof (struct prefix));
556
557 info = (struct ospf6_external_info *)
558 XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
559 memset (info, 0, sizeof (struct ospf6_external_info));
560 route->route_option = info;
561 info->id = ospf6->external_id++;
562
563 /* copy result of route-map */
564 if (ospf6->rmap[type].map)
565 {
566 if (troute.path.metric_type)
567 route->path.metric_type = troute.path.metric_type;
568 if (troute.path.cost)
569 route->path.cost = troute.path.cost;
570 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
571 memcpy (&info->forwarding, &tinfo.forwarding,
572 sizeof (struct in6_addr));
573 }
574
575 info->type = type;
576 route->nexthop[0].ifindex = ifindex;
577 if (nexthop_num && nexthop)
578 memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
579
580 /* create/update binding in external_id_table */
581 prefix_id.family = AF_INET;
582 prefix_id.prefixlen = 32;
583 prefix_id.u.prefix4.s_addr = htonl (info->id);
584 node = route_node_get (ospf6->external_id_table, &prefix_id);
585 node->info = route;
586
587 route = ospf6_route_add (route, ospf6->external_table);
588 route->route_option = info;
589
590 if (IS_OSPF6_DEBUG_ASBR)
591 {
592 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
593 zlog_info ("Advertise as AS-External Id:%s", ibuf);
594 }
595
596 ospf6_as_external_lsa_originate_sub (route, 0);
597
598 /* Router-Bit (ASBR Flag) may have to be updated */
599 for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode))
600 {
601 oa = (struct ospf6_area *) getdata (lnode);
602 OSPF6_ROUTER_LSA_SCHEDULE (oa);
603 }
604}
605
606void
607ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
608{
609 struct ospf6_route *match;
610 struct ospf6_external_info *info = NULL;
611 struct route_node *node;
612 struct ospf6_lsa *lsa;
613 struct prefix prefix_id;
614 char pbuf[64], ibuf[16];
615 listnode lnode;
616 struct ospf6_area *oa;
617
618 match = ospf6_route_lookup (prefix, ospf6->external_table);
619 if (match == NULL)
620 {
621 if (IS_OSPF6_DEBUG_ASBR)
622 {
623 prefix2str (prefix, pbuf, sizeof (pbuf));
624 zlog_info ("No such route %s to withdraw", pbuf);
625 }
626 return;
627 }
628
629 info = match->route_option;
630 assert (info);
631
632 if (info->type != type)
633 {
634 if (IS_OSPF6_DEBUG_ASBR)
635 {
636 prefix2str (prefix, pbuf, sizeof (pbuf));
637 zlog_info ("Original protocol mismatch: %s", pbuf);
638 }
639 return;
640 }
641
642 if (IS_OSPF6_DEBUG_ASBR)
643 {
644 prefix2str (prefix, pbuf, sizeof (pbuf));
645 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
646 zlog_info ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
647 }
648
649 lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
650 htonl (info->id), ospf6->router_id, ospf6->lsdb);
651 if (lsa)
652 ospf6_lsa_premature_aging (lsa);
653
654 /* remove binding in external_id_table */
655 prefix_id.family = AF_INET;
656 prefix_id.prefixlen = 32;
657 prefix_id.u.prefix4.s_addr = htonl (info->id);
658 node = route_node_lookup (ospf6->external_id_table, &prefix_id);
659 assert (node);
660 node->info = NULL;
661 route_unlock_node (node);
662
663 ospf6_route_remove (match, ospf6->external_table);
664 XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
665
666 /* Router-Bit (ASBR Flag) may have to be updated */
667 for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode))
668 {
669 oa = (struct ospf6_area *) getdata (lnode);
670 OSPF6_ROUTER_LSA_SCHEDULE (oa);
paul718e3742002-12-13 20:15:29 +0000671 }
672}
673
674DEFUN (ospf6_redistribute,
675 ospf6_redistribute_cmd,
676 "redistribute (static|kernel|connected|ripng|bgp)",
677 "Redistribute\n"
678 "Static route\n"
679 "Kernel route\n"
680 "Connected route\n"
681 "RIPng route\n"
682 "BGP route\n"
683 )
684{
685 int type = 0;
686
687 if (strncmp (argv[0], "sta", 3) == 0)
688 type = ZEBRA_ROUTE_STATIC;
689 else if (strncmp (argv[0], "ker", 3) == 0)
690 type = ZEBRA_ROUTE_KERNEL;
691 else if (strncmp (argv[0], "con", 3) == 0)
692 type = ZEBRA_ROUTE_CONNECT;
693 else if (strncmp (argv[0], "rip", 3) == 0)
694 type = ZEBRA_ROUTE_RIPNG;
695 else if (strncmp (argv[0], "bgp", 3) == 0)
696 type = ZEBRA_ROUTE_BGP;
697
hasso508e53e2004-05-18 18:57:06 +0000698 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000699 ospf6_asbr_routemap_unset (type);
hasso508e53e2004-05-18 18:57:06 +0000700 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000701 return CMD_SUCCESS;
702}
703
704DEFUN (ospf6_redistribute_routemap,
705 ospf6_redistribute_routemap_cmd,
706 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
707 "Redistribute\n"
708 "Static routes\n"
709 "Kernel route\n"
710 "Connected route\n"
711 "RIPng route\n"
712 "BGP route\n"
713 "Route map reference\n"
714 "Route map name\n"
715 )
716{
717 int type = 0;
718
719 if (strncmp (argv[0], "sta", 3) == 0)
720 type = ZEBRA_ROUTE_STATIC;
721 else if (strncmp (argv[0], "ker", 3) == 0)
722 type = ZEBRA_ROUTE_KERNEL;
723 else if (strncmp (argv[0], "con", 3) == 0)
724 type = ZEBRA_ROUTE_CONNECT;
725 else if (strncmp (argv[0], "rip", 3) == 0)
726 type = ZEBRA_ROUTE_RIPNG;
727 else if (strncmp (argv[0], "bgp", 3) == 0)
728 type = ZEBRA_ROUTE_BGP;
729
hasso508e53e2004-05-18 18:57:06 +0000730 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000731 ospf6_asbr_routemap_set (type, argv[1]);
hasso508e53e2004-05-18 18:57:06 +0000732 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000733 return CMD_SUCCESS;
734}
735
736DEFUN (no_ospf6_redistribute,
737 no_ospf6_redistribute_cmd,
738 "no redistribute (static|kernel|connected|ripng|bgp)",
739 NO_STR
740 "Redistribute\n"
741 "Static route\n"
742 "Kernel route\n"
743 "Connected route\n"
744 "RIPng route\n"
745 "BGP route\n"
746 )
747{
748 int type = 0;
paul718e3742002-12-13 20:15:29 +0000749
750 if (strncmp (argv[0], "sta", 3) == 0)
751 type = ZEBRA_ROUTE_STATIC;
752 else if (strncmp (argv[0], "ker", 3) == 0)
753 type = ZEBRA_ROUTE_KERNEL;
754 else if (strncmp (argv[0], "con", 3) == 0)
755 type = ZEBRA_ROUTE_CONNECT;
756 else if (strncmp (argv[0], "rip", 3) == 0)
757 type = ZEBRA_ROUTE_RIPNG;
758 else if (strncmp (argv[0], "bgp", 3) == 0)
759 type = ZEBRA_ROUTE_BGP;
760
hasso508e53e2004-05-18 18:57:06 +0000761 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000762 ospf6_asbr_routemap_unset (type);
763
paul718e3742002-12-13 20:15:29 +0000764 return CMD_SUCCESS;
765}
766
paul718e3742002-12-13 20:15:29 +0000767int
768ospf6_redistribute_config_write (struct vty *vty)
769{
hasso508e53e2004-05-18 18:57:06 +0000770 int type;
paul718e3742002-12-13 20:15:29 +0000771
hasso508e53e2004-05-18 18:57:06 +0000772 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000773 {
hasso508e53e2004-05-18 18:57:06 +0000774 if (type == ZEBRA_ROUTE_OSPF6)
775 continue;
776 if (! ospf6_zebra_is_redistribute (type))
paul718e3742002-12-13 20:15:29 +0000777 continue;
778
hasso508e53e2004-05-18 18:57:06 +0000779 if (ospf6->rmap[type].name)
paul718e3742002-12-13 20:15:29 +0000780 vty_out (vty, " redistribute %s route-map %s%s",
hasso049207c2004-08-04 20:02:13 +0000781 ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
paul718e3742002-12-13 20:15:29 +0000782 else
783 vty_out (vty, " redistribute %s%s",
hasso049207c2004-08-04 20:02:13 +0000784 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000785 }
786
787 return 0;
788}
789
790void
791ospf6_redistribute_show_config (struct vty *vty)
792{
hasso508e53e2004-05-18 18:57:06 +0000793 int type;
794 int nroute[ZEBRA_ROUTE_MAX];
795 int total;
796 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000797 struct ospf6_external_info *info;
paul718e3742002-12-13 20:15:29 +0000798
hasso508e53e2004-05-18 18:57:06 +0000799 total = 0;
800 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
801 nroute[type] = 0;
802 for (route = ospf6_route_head (ospf6->external_table); route;
803 route = ospf6_route_next (route))
paul718e3742002-12-13 20:15:29 +0000804 {
hasso508e53e2004-05-18 18:57:06 +0000805 info = route->route_option;
806 nroute[info->type]++;
807 total++;
paul718e3742002-12-13 20:15:29 +0000808 }
809
hasso049207c2004-08-04 20:02:13 +0000810 vty_out (vty, "Redistributing External Routes from:%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000811 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000812 {
hasso508e53e2004-05-18 18:57:06 +0000813 if (type == ZEBRA_ROUTE_OSPF6)
814 continue;
815 if (! ospf6_zebra_is_redistribute (type))
hassoe26bbeb2003-05-25 21:39:29 +0000816 continue;
817
hasso508e53e2004-05-18 18:57:06 +0000818 if (ospf6->rmap[type].name)
819 vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
820 ZROUTE_NAME (type), ospf6->rmap[type].name,
821 (ospf6->rmap[type].map ? "" : " (not found !)"),
hasso049207c2004-08-04 20:02:13 +0000822 VNL);
paul718e3742002-12-13 20:15:29 +0000823 else
hasso508e53e2004-05-18 18:57:06 +0000824 vty_out (vty, " %d: %s%s", nroute[type],
hasso049207c2004-08-04 20:02:13 +0000825 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000826 }
hasso049207c2004-08-04 20:02:13 +0000827 vty_out (vty, "Total %d routes%s", total, VNL);
hasso508e53e2004-05-18 18:57:06 +0000828}
paul718e3742002-12-13 20:15:29 +0000829
paul718e3742002-12-13 20:15:29 +0000830
hasso508e53e2004-05-18 18:57:06 +0000831
832/* Routemap Functions */
833route_map_result_t
834ospf6_routemap_rule_match_address_prefixlist (void *rule,
835 struct prefix *prefix,
836 route_map_object_t type,
837 void *object)
838{
839 struct prefix_list *plist;
paul718e3742002-12-13 20:15:29 +0000840
hasso508e53e2004-05-18 18:57:06 +0000841 if (type != RMAP_OSPF6)
842 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000843
hasso508e53e2004-05-18 18:57:06 +0000844 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
845 if (plist == NULL)
846 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000847
hasso508e53e2004-05-18 18:57:06 +0000848 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
849 RMAP_NOMATCH : RMAP_MATCH);
850}
paul718e3742002-12-13 20:15:29 +0000851
hasso508e53e2004-05-18 18:57:06 +0000852void *
853ospf6_routemap_rule_match_address_prefixlist_compile (char *arg)
854{
855 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000856}
857
858void
hasso508e53e2004-05-18 18:57:06 +0000859ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000860{
hasso508e53e2004-05-18 18:57:06 +0000861 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
862}
paul718e3742002-12-13 20:15:29 +0000863
hasso508e53e2004-05-18 18:57:06 +0000864struct route_map_rule_cmd
865ospf6_routemap_rule_match_address_prefixlist_cmd =
866{
867 "ipv6 address prefix-list",
868 ospf6_routemap_rule_match_address_prefixlist,
869 ospf6_routemap_rule_match_address_prefixlist_compile,
870 ospf6_routemap_rule_match_address_prefixlist_free,
871};
hassoe26bbeb2003-05-25 21:39:29 +0000872
hasso508e53e2004-05-18 18:57:06 +0000873route_map_result_t
874ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
875 route_map_object_t type, void *object)
876{
877 char *metric_type = rule;
878 struct ospf6_route *route = object;
hassoe26bbeb2003-05-25 21:39:29 +0000879
hasso508e53e2004-05-18 18:57:06 +0000880 if (type != RMAP_OSPF6)
881 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000882
hasso508e53e2004-05-18 18:57:06 +0000883 if (strcmp (metric_type, "type-2") == 0)
884 route->path.metric_type = 2;
paul718e3742002-12-13 20:15:29 +0000885 else
hasso508e53e2004-05-18 18:57:06 +0000886 route->path.metric_type = 1;
paul718e3742002-12-13 20:15:29 +0000887
hasso508e53e2004-05-18 18:57:06 +0000888 return RMAP_OKAY;
889}
paul718e3742002-12-13 20:15:29 +0000890
hasso508e53e2004-05-18 18:57:06 +0000891void *
892ospf6_routemap_rule_set_metric_type_compile (char *arg)
893{
894 if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
895 return NULL;
896 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000897}
898
899void
hasso508e53e2004-05-18 18:57:06 +0000900ospf6_routemap_rule_set_metric_type_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000901{
hasso508e53e2004-05-18 18:57:06 +0000902 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
903}
paul718e3742002-12-13 20:15:29 +0000904
hasso508e53e2004-05-18 18:57:06 +0000905struct route_map_rule_cmd
906ospf6_routemap_rule_set_metric_type_cmd =
907{
908 "metric-type",
909 ospf6_routemap_rule_set_metric_type,
910 ospf6_routemap_rule_set_metric_type_compile,
911 ospf6_routemap_rule_set_metric_type_free,
912};
paul718e3742002-12-13 20:15:29 +0000913
hasso508e53e2004-05-18 18:57:06 +0000914route_map_result_t
915ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
916 route_map_object_t type, void *object)
917{
918 char *metric = rule;
919 struct ospf6_route *route = object;
paul718e3742002-12-13 20:15:29 +0000920
hasso508e53e2004-05-18 18:57:06 +0000921 if (type != RMAP_OSPF6)
922 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000923
hasso508e53e2004-05-18 18:57:06 +0000924 route->path.cost = atoi (metric);
925 return RMAP_OKAY;
926}
paul718e3742002-12-13 20:15:29 +0000927
hasso508e53e2004-05-18 18:57:06 +0000928void *
929ospf6_routemap_rule_set_metric_compile (char *arg)
930{
931 u_int32_t metric;
932 char *endp;
933 metric = strtoul (arg, &endp, 0);
934 if (metric > LS_INFINITY || *endp != '\0')
935 return NULL;
936 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000937}
938
939void
hasso508e53e2004-05-18 18:57:06 +0000940ospf6_routemap_rule_set_metric_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000941{
hasso508e53e2004-05-18 18:57:06 +0000942 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
943}
944
945struct route_map_rule_cmd
946ospf6_routemap_rule_set_metric_cmd =
947{
948 "metric",
949 ospf6_routemap_rule_set_metric,
950 ospf6_routemap_rule_set_metric_compile,
951 ospf6_routemap_rule_set_metric_free,
952};
953
954route_map_result_t
955ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
956 route_map_object_t type, void *object)
957{
958 char *forwarding = rule;
959 struct ospf6_route *route = object;
960 struct ospf6_external_info *info = route->route_option;
961
962 if (type != RMAP_OSPF6)
963 return RMAP_OKAY;
964
965 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
966 {
967 memset (&info->forwarding, 0, sizeof (struct in6_addr));
968 return RMAP_ERROR;
969 }
970
971 return RMAP_OKAY;
972}
973
974void *
975ospf6_routemap_rule_set_forwarding_compile (char *arg)
976{
977 struct in6_addr a;
978 if (inet_pton (AF_INET6, arg, &a) != 1)
979 return NULL;
980 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
981}
982
983void
984ospf6_routemap_rule_set_forwarding_free (void *rule)
985{
986 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
987}
988
989struct route_map_rule_cmd
990ospf6_routemap_rule_set_forwarding_cmd =
991{
992 "forwarding-address",
993 ospf6_routemap_rule_set_forwarding,
994 ospf6_routemap_rule_set_forwarding_compile,
995 ospf6_routemap_rule_set_forwarding_free,
996};
997
998int
999route_map_command_status (struct vty *vty, int ret)
1000{
1001 if (! ret)
1002 return CMD_SUCCESS;
1003
1004 switch (ret)
1005 {
1006 case RMAP_RULE_MISSING:
hasso049207c2004-08-04 20:02:13 +00001007 vty_out (vty, "Can't find rule.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001008 break;
1009 case RMAP_COMPILE_ERROR:
hasso049207c2004-08-04 20:02:13 +00001010 vty_out (vty, "Argument is malformed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001011 break;
1012 default:
hasso049207c2004-08-04 20:02:13 +00001013 vty_out (vty, "route-map add set failed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001014 break;
1015 }
1016 return CMD_WARNING;
1017}
1018
1019/* add "match address" */
1020DEFUN (ospf6_routemap_match_address_prefixlist,
1021 ospf6_routemap_match_address_prefixlist_cmd,
1022 "match ipv6 address prefix-list WORD",
1023 "Match values\n"
1024 IPV6_STR
1025 "Match address of route\n"
1026 "Match entries of prefix-lists\n"
1027 "IPv6 prefix-list name\n")
1028{
1029 int ret = route_map_add_match ((struct route_map_index *) vty->index,
1030 "ipv6 address prefix-list", argv[0]);
1031 return route_map_command_status (vty, ret);
1032}
1033
1034/* delete "match address" */
1035DEFUN (ospf6_routemap_no_match_address_prefixlist,
1036 ospf6_routemap_no_match_address_prefixlist_cmd,
1037 "no match ipv6 address prefix-list WORD",
1038 NO_STR
1039 "Match values\n"
1040 IPV6_STR
1041 "Match address of route\n"
1042 "Match entries of prefix-lists\n"
1043 "IPv6 prefix-list name\n")
1044{
1045 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1046 "ipv6 address prefix-list", argv[0]);
1047 return route_map_command_status (vty, ret);
1048}
1049
1050/* add "set metric-type" */
1051DEFUN (ospf6_routemap_set_metric_type,
1052 ospf6_routemap_set_metric_type_cmd,
1053 "set metric-type (type-1|type-2)",
1054 "Set value\n"
1055 "Type of metric\n"
1056 "OSPF6 external type 1 metric\n"
1057 "OSPF6 external type 2 metric\n")
1058{
1059 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1060 "metric-type", argv[0]);
1061 return route_map_command_status (vty, ret);
1062}
1063
1064/* delete "set metric-type" */
1065DEFUN (ospf6_routemap_no_set_metric_type,
1066 ospf6_routemap_no_set_metric_type_cmd,
1067 "no set metric-type (type-1|type-2)",
1068 NO_STR
1069 "Set value\n"
1070 "Type of metric\n"
1071 "OSPF6 external type 1 metric\n"
1072 "OSPF6 external type 2 metric\n")
1073{
1074 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1075 "metric-type", argv[0]);
1076 return route_map_command_status (vty, ret);
1077}
1078
1079/* add "set metric" */
1080DEFUN (set_metric,
1081 set_metric_cmd,
1082 "set metric <0-4294967295>",
1083 "Set value\n"
1084 "Metric value\n"
1085 "Metric value\n")
1086{
1087 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1088 "metric", argv[0]);
1089 return route_map_command_status (vty, ret);
1090}
1091
1092/* delete "set metric" */
1093DEFUN (no_set_metric,
1094 no_set_metric_cmd,
1095 "no set metric <0-4294967295>",
1096 NO_STR
1097 "Set value\n"
1098 "Metric\n"
1099 "METRIC value\n")
1100{
1101 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1102 "metric", argv[0]);
1103 return route_map_command_status (vty, ret);
1104}
1105
1106/* add "set forwarding-address" */
1107DEFUN (ospf6_routemap_set_forwarding,
1108 ospf6_routemap_set_forwarding_cmd,
1109 "set forwarding-address X:X::X:X",
1110 "Set value\n"
1111 "Forwarding Address\n"
1112 "IPv6 Address\n")
1113{
1114 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1115 "forwarding-address", argv[0]);
1116 return route_map_command_status (vty, ret);
1117}
1118
1119/* delete "set forwarding-address" */
1120DEFUN (ospf6_routemap_no_set_forwarding,
1121 ospf6_routemap_no_set_forwarding_cmd,
1122 "no set forwarding-address X:X::X:X",
1123 NO_STR
1124 "Set value\n"
1125 "Forwarding Address\n"
1126 "IPv6 Address\n")
1127{
1128 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1129 "forwarding-address", argv[0]);
1130 return route_map_command_status (vty, ret);
1131}
1132
1133void
1134ospf6_routemap_init ()
1135{
1136 route_map_init ();
1137 route_map_init_vty ();
1138 route_map_add_hook (ospf6_asbr_routemap_update);
1139 route_map_delete_hook (ospf6_asbr_routemap_update);
1140
1141 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
1142 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
1143 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
1144 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
1145
1146 /* Match address prefix-list */
1147 install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
1148 install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
1149
1150 /* ASE Metric Type (e.g. Type-1/Type-2) */
1151 install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
1152 install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
1153
1154 /* ASE Metric */
1155 install_element (RMAP_NODE, &set_metric_cmd);
1156 install_element (RMAP_NODE, &no_set_metric_cmd);
1157
1158 /* ASE Metric */
1159 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
1160 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
1161}
1162
1163
1164/* Display functions */
1165int
1166ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
1167{
1168 struct ospf6_as_external_lsa *external;
paul718e3742002-12-13 20:15:29 +00001169 char buf[64];
hasso508e53e2004-05-18 18:57:06 +00001170 struct in6_addr in6, *forwarding;
paul718e3742002-12-13 20:15:29 +00001171
1172 assert (lsa->header);
hasso508e53e2004-05-18 18:57:06 +00001173 external = (struct ospf6_as_external_lsa *)
1174 OSPF6_LSA_HEADER_END (lsa->header);
paul718e3742002-12-13 20:15:29 +00001175
1176 /* bits */
hasso508e53e2004-05-18 18:57:06 +00001177 snprintf (buf, sizeof (buf), "%c%c%c",
1178 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
1179 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
1180 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
paul718e3742002-12-13 20:15:29 +00001181
hasso049207c2004-08-04 20:02:13 +00001182 vty_out (vty, " Bits: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +00001183 vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
hasso049207c2004-08-04 20:02:13 +00001184 VNL);
paul718e3742002-12-13 20:15:29 +00001185
hasso508e53e2004-05-18 18:57:06 +00001186 ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1187 buf, sizeof (buf));
1188 vty_out (vty, " Prefix Options: %s%s", buf,
hasso049207c2004-08-04 20:02:13 +00001189 VNL);
paul718e3742002-12-13 20:15:29 +00001190
1191 vty_out (vty, " Referenced LSType: %d%s",
hasso508e53e2004-05-18 18:57:06 +00001192 ntohs (external->prefix.prefix_refer_lstype),
hasso049207c2004-08-04 20:02:13 +00001193 VNL);
paul718e3742002-12-13 20:15:29 +00001194
hasso508e53e2004-05-18 18:57:06 +00001195 ospf6_prefix_in6_addr (&in6, &external->prefix);
paul718e3742002-12-13 20:15:29 +00001196 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
hasso508e53e2004-05-18 18:57:06 +00001197 vty_out (vty, " Prefix: %s/%d%s", buf,
hasso049207c2004-08-04 20:02:13 +00001198 external->prefix.prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +00001199
1200 /* Forwarding-Address */
1201 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
1202 {
hasso508e53e2004-05-18 18:57:06 +00001203 forwarding = (struct in6_addr *)
1204 ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
1205 OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
1206 inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +00001207 vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
paul718e3742002-12-13 20:15:29 +00001208 }
1209
1210 return 0;
1211}
1212
1213void
hasso508e53e2004-05-18 18:57:06 +00001214ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +00001215{
hasso508e53e2004-05-18 18:57:06 +00001216 struct ospf6_external_info *info = route->route_option;
1217 char prefix[64], id[16], forwarding[64];
1218 u_int32_t tmp_id;
1219
1220 prefix2str (&route->prefix, prefix, sizeof (prefix));
1221 tmp_id = ntohl (info->id);
1222 inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
1223 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
1224 inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
1225 else
1226 snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
1227 route->nexthop[0].ifindex);
1228
1229 vty_out (vty, "%s %-32s %-15s type-%d %5lu %s%s",
1230 ZROUTE_ABNAME (info->type),
1231 prefix, id, route->path.metric_type,
1232 (u_long) (route->path.metric_type == 2 ?
1233 route->path.cost_e2 : route->path.cost),
hasso049207c2004-08-04 20:02:13 +00001234 forwarding, VNL);
paul718e3742002-12-13 20:15:29 +00001235}
1236
hasso508e53e2004-05-18 18:57:06 +00001237DEFUN (show_ipv6_ospf6_redistribute,
1238 show_ipv6_ospf6_redistribute_cmd,
1239 "show ipv6 ospf6 redistribute",
paul718e3742002-12-13 20:15:29 +00001240 SHOW_STR
1241 IP6_STR
paul718e3742002-12-13 20:15:29 +00001242 OSPF6_STR
1243 "redistributing External information\n"
1244 )
1245{
hasso508e53e2004-05-18 18:57:06 +00001246 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +00001247
hasso508e53e2004-05-18 18:57:06 +00001248 ospf6_redistribute_show_config (vty);
1249
1250 for (route = ospf6_route_head (ospf6->external_table); route;
1251 route = ospf6_route_next (route))
1252 ospf6_asbr_external_route_show (vty, route);
1253
paul718e3742002-12-13 20:15:29 +00001254 return CMD_SUCCESS;
1255}
1256
hasso508e53e2004-05-18 18:57:06 +00001257DEFUN (show_ipv6_ospf6_asbr,
1258 show_ipv6_ospf6_asbr_cmd,
1259 "show ipv6 ospf6 asbr",
1260 SHOW_STR
1261 IP6_STR
1262 OSPF6_STR
1263 "Show AS Boundary Router table\n"
1264 )
1265{
1266 ospf6_lsentry_table_show (vty, argc, argv, ospf6->asbr_table);
1267 return CMD_SUCCESS;
1268}
1269
1270ALIAS (show_ipv6_ospf6_asbr,
1271 show_ipv6_ospf6_asbr_1_cmd,
1272 "show ipv6 ospf6 asbr (A.B.C.D|A.B.C.D/M|detail)",
1273 SHOW_STR
1274 IP6_STR
1275 OSPF6_STR
1276 "Show AS Boundary Router table\n"
1277 "Specify Router-ID\n"
1278 "Display multiple entry by specifying match-prefix of Router-ID\n"
1279 "Display Detail\n"
1280 );
1281
1282ALIAS (show_ipv6_ospf6_asbr,
1283 show_ipv6_ospf6_asbr_2_cmd,
1284 "show ipv6 ospf6 asbr (A.B.C.D|A.B.C.D/M|*) (A.B.C.D|A.B.C.D/M|detail)",
1285 SHOW_STR
1286 IP6_STR
1287 OSPF6_STR
1288 "Show AS Boundary Router table\n"
1289 "Specify Router-ID\n"
1290 "Display multiple entry by specifying match-prefix of Router-ID\n"
1291 "Wildcard Router-ID\n"
1292 "Specify Link State ID\n"
1293 "Display multiple entry by specifying match-prefix of Link State ID\n"
1294 "Display Detail\n"
1295 );
1296
1297DEFUN (show_ipv6_ospf6_asbr_3,
1298 show_ipv6_ospf6_asbr_3_cmd,
1299 "show ipv6 ospf6 asbr (A.B.C.D|*) A.B.C.D/M detail",
1300 SHOW_STR
1301 IP6_STR
1302 OSPF6_STR
1303 "Show AS Boundary Router table\n"
1304 "Specify Router-ID\n"
1305 "Wildcard Router-ID\n"
1306 "Display multiple entry by specifying match-prefix of Link State ID\n"
1307 "Display Detail\n"
1308 )
1309{
1310 char *sargv[CMD_ARGC_MAX];
1311 int i, sargc;
1312
1313 /* copy argv to sargv and then append "detail" */
1314 for (i = 0; i < argc; i++)
1315 sargv[i] = argv[i];
1316 sargc = argc;
1317 sargv[sargc++] = "detail";
1318 sargv[sargc] = NULL;
1319
1320 ospf6_lsentry_table_show (vty, sargc, sargv, ospf6->asbr_table);
1321 return CMD_SUCCESS;
1322}
1323
1324
paul718e3742002-12-13 20:15:29 +00001325void
1326ospf6_asbr_init ()
1327{
hasso508e53e2004-05-18 18:57:06 +00001328 ospf6_routemap_init ();
paul718e3742002-12-13 20:15:29 +00001329
hasso508e53e2004-05-18 18:57:06 +00001330 ospf6_lstype[5].name = "AS-External";
1331 ospf6_lstype[5].reoriginate = ospf6_as_external_lsa_reoriginate;
1332 ospf6_lstype[5].show = ospf6_as_external_lsa_show;
paul718e3742002-12-13 20:15:29 +00001333
hasso508e53e2004-05-18 18:57:06 +00001334 install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
1335 install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
1336
1337 install_element (VIEW_NODE, &show_ipv6_ospf6_asbr_cmd);
1338 install_element (VIEW_NODE, &show_ipv6_ospf6_asbr_1_cmd);
1339 install_element (VIEW_NODE, &show_ipv6_ospf6_asbr_2_cmd);
1340 install_element (VIEW_NODE, &show_ipv6_ospf6_asbr_3_cmd);
1341 install_element (ENABLE_NODE, &show_ipv6_ospf6_asbr_cmd);
1342 install_element (ENABLE_NODE, &show_ipv6_ospf6_asbr_1_cmd);
1343 install_element (ENABLE_NODE, &show_ipv6_ospf6_asbr_2_cmd);
1344 install_element (ENABLE_NODE, &show_ipv6_ospf6_asbr_3_cmd);
1345
paul718e3742002-12-13 20:15:29 +00001346 install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
1347 install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
1348 install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
1349}
1350
1351
hasso508e53e2004-05-18 18:57:06 +00001352DEFUN (debug_ospf6_asbr,
1353 debug_ospf6_asbr_cmd,
1354 "debug ospf6 asbr",
1355 DEBUG_STR
1356 OSPF6_STR
1357 "Debug OSPFv3 ASBR function\n"
1358 )
1359{
1360 OSPF6_DEBUG_ASBR_ON ();
1361 return CMD_SUCCESS;
1362}
1363
1364DEFUN (no_debug_ospf6_asbr,
1365 no_debug_ospf6_asbr_cmd,
1366 "no debug ospf6 asbr",
1367 NO_STR
1368 DEBUG_STR
1369 OSPF6_STR
1370 "Debug OSPFv3 ASBR function\n"
1371 )
1372{
1373 OSPF6_DEBUG_ASBR_OFF ();
1374 return CMD_SUCCESS;
1375}
1376
1377int
1378config_write_ospf6_debug_asbr (struct vty *vty)
1379{
1380 if (IS_OSPF6_DEBUG_ASBR)
hasso049207c2004-08-04 20:02:13 +00001381 vty_out (vty, "debug ospf6 asbr%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001382 return 0;
1383}
1384
1385void
1386install_element_ospf6_debug_asbr ()
1387{
1388 install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
1389 install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
1390 install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
1391 install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
1392}
1393
1394