blob: 7884a6bf64de32bd136a9c9414b8bae0ea6314de [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"
hasso6452df02004-08-15 05:52:07 +000040#include "ospf6_message.h"
41
hasso508e53e2004-05-18 18:57:06 +000042#include "ospf6_top.h"
43#include "ospf6_area.h"
hasso6452df02004-08-15 05:52:07 +000044#include "ospf6_interface.h"
45#include "ospf6_neighbor.h"
hasso508e53e2004-05-18 18:57:06 +000046#include "ospf6_asbr.h"
47#include "ospf6_intra.h"
hasso6452df02004-08-15 05:52:07 +000048#include "ospf6_flood.h"
hasso049207c2004-08-04 20:02:13 +000049#include "ospf6d.h"
paul718e3742002-12-13 20:15:29 +000050
hasso508e53e2004-05-18 18:57:06 +000051unsigned char conf_debug_ospf6_asbr = 0;
paul718e3742002-12-13 20:15:29 +000052
hasso508e53e2004-05-18 18:57:06 +000053char *zroute_name[] =
54{ "system", "kernel", "connected", "static",
hasso3b4cd3a2004-05-18 19:28:32 +000055 "rip", "ripng", "ospf", "ospf6", "isis", "bgp", "unknown" };
hasso508e53e2004-05-18 18:57:06 +000056
57char *zroute_abname[] =
hasso3b4cd3a2004-05-18 19:28:32 +000058{ "X", "K", "C", "S", "R", "R", "O", "O", "I", "B", "?" };
hasso508e53e2004-05-18 18:57:06 +000059
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])
66
67/* AS External LSA origination */
68void
hasso6452df02004-08-15 05:52:07 +000069ospf6_as_external_lsa_originate (struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +000070{
hasso508e53e2004-05-18 18:57:06 +000071 char buffer[OSPF6_MAX_LSASIZE];
72 struct ospf6_lsa_header *lsa_header;
73 struct ospf6_lsa *old, *lsa;
paul718e3742002-12-13 20:15:29 +000074
hasso508e53e2004-05-18 18:57:06 +000075 struct ospf6_as_external_lsa *as_external_lsa;
76 char buf[64];
77 caddr_t p;
paul718e3742002-12-13 20:15:29 +000078
hasso508e53e2004-05-18 18:57:06 +000079 /* find previous LSA */
80 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
hasso6452df02004-08-15 05:52:07 +000081 route->path.origin.id, ospf6->router_id,
hasso508e53e2004-05-18 18:57:06 +000082 ospf6->lsdb);
83
84 if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
85 {
86 prefix2str (&route->prefix, buf, sizeof (buf));
87 zlog_info ("Originate AS-External-LSA for %s", buf);
88 }
89
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));
97
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);
104
105 /* forwarding address */
hasso6452df02004-08-15 05:52:07 +0000106 if (! IN6_IS_ADDR_UNSPECIFIED (&route->nexthop[0].address))
hasso508e53e2004-05-18 18:57:06 +0000107 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);
110
111 /* external route tag */
112 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
113
114 /* Set metric */
115 OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
116
117 /* prefixlen */
118 as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
119
120 /* PrefixOptions */
121 as_external_lsa->prefix.prefix_options = route->path.prefix_options;
122
123 /* don't use refer LS-type */
124 as_external_lsa->prefix.prefix_refer_lstype = htons (0);
125
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);
131
132 /* Forwarding address */
133 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
134 {
hasso6452df02004-08-15 05:52:07 +0000135 memcpy (p, &route->nexthop[0].address, sizeof (struct in6_addr));
hasso508e53e2004-05-18 18:57:06 +0000136 p += sizeof (struct in6_addr);
137 }
138
139 /* External Route Tag */
140 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
141 {
142 /* xxx */
143 }
144
145 /* Fill LSA Header */
146 lsa_header->age = 0;
147 lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
hasso6452df02004-08-15 05:52:07 +0000148 lsa_header->id = route->path.origin.id;
hasso508e53e2004-05-18 18:57:06 +0000149 lsa_header->adv_router = ospf6->router_id;
150 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000151 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
152 lsa_header->adv_router, ospf6->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000153 lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
154
155 /* LSA checksum */
156 ospf6_lsa_checksum (lsa_header);
157
158 /* create LSA */
159 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000160
161 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000162 ospf6_lsa_originate_process (lsa, ospf6);
hasso508e53e2004-05-18 18:57:06 +0000163}
164
hasso508e53e2004-05-18 18:57:06 +0000165
166void
167ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
168{
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;
174
175 external = (struct ospf6_as_external_lsa *)
176 OSPF6_LSA_HEADER_END (lsa->header);
177
178 if (IS_OSPF6_DEBUG_ASBR)
179 zlog_info ("Calculate AS-External route for %s", lsa->name);
180
181 if (lsa->header->adv_router == ospf6->router_id)
182 {
183 if (IS_OSPF6_DEBUG_ASBR)
184 zlog_info ("Ignore self-originated AS-External-LSA");
185 return;
186 }
187
188 if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
189 {
190 if (IS_OSPF6_DEBUG_ASBR)
191 zlog_info ("Ignore LSA with LSInfinity Metric");
192 return;
193 }
194
195 asbr_id.family = AF_INET;
196 asbr_id.prefixlen = 32;
197 asbr_id.u.prefix4.s_addr = lsa->header->adv_router;
hasso6452df02004-08-15 05:52:07 +0000198 asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
hasso508e53e2004-05-18 18:57:06 +0000199
200 if (asbr_entry == NULL)
201 {
202 if (IS_OSPF6_DEBUG_ASBR)
203 {
204 prefix2str (&asbr_id, buf, sizeof (buf));
205 zlog_info ("ASBR entry not found: %s", buf);
206 }
207 return;
208 }
209
210 route = ospf6_route_create ();
211 route->type = OSPF6_DEST_TYPE_NETWORK;
212 route->prefix.family = AF_INET6;
213 route->prefix.prefixlen = external->prefix.prefix_length;
214 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
215
216 route->path.area_id = asbr_entry->path.area_id;
217 route->path.origin.type = lsa->header->type;
218 route->path.origin.id = lsa->header->id;
219 route->path.origin.adv_router = lsa->header->adv_router;
220
221 route->path.prefix_options = external->prefix.prefix_options;
222 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
223 {
224 route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
225 route->path.metric_type = 2;
226 route->path.cost = asbr_entry->path.cost;
227 route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
228 }
229 else
230 {
231 route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
232 route->path.metric_type = 1;
233 route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
234 route->path.cost_e2 = 0;
235 }
236
237 for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
238 ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
239
240 if (IS_OSPF6_DEBUG_ASBR)
241 {
242 prefix2str (&route->prefix, buf, sizeof (buf));
243 zlog_info ("AS-External route add: %s", buf);
244 }
245
246 ospf6_route_add (route, ospf6->route_table);
247}
248
249void
250ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
251{
252 struct ospf6_as_external_lsa *external;
253 struct prefix prefix;
254 struct ospf6_route *route;
255 char buf[64];
256
257 external = (struct ospf6_as_external_lsa *)
258 OSPF6_LSA_HEADER_END (lsa->header);
259
260 if (IS_OSPF6_DEBUG_ASBR)
261 zlog_info ("Withdraw AS-External route for %s", lsa->name);
262
263 if (lsa->header->adv_router == ospf6->router_id)
264 {
265 if (IS_OSPF6_DEBUG_ASBR)
266 zlog_info ("Ignore self-originated AS-External-LSA");
267 return;
268 }
269
270 memset (&prefix, 0, sizeof (struct prefix));
271 prefix.family = AF_INET6;
272 prefix.prefixlen = external->prefix.prefix_length;
273 ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
274
275 route = ospf6_route_lookup (&prefix, ospf6->route_table);
276 if (route == NULL)
277 {
278 if (IS_OSPF6_DEBUG_ASBR)
279 {
280 prefix2str (&prefix, buf, sizeof (buf));
281 zlog_info ("AS-External route %s not found", buf);
282 }
283 return;
284 }
285
286 for (ospf6_route_lock (route);
287 route && ospf6_route_is_prefix (&prefix, route);
288 route = ospf6_route_next (route))
289 {
290 if (route->type != OSPF6_DEST_TYPE_NETWORK)
291 continue;
292 if (route->path.origin.type != lsa->header->type)
293 continue;
294 if (route->path.origin.id != lsa->header->id)
295 continue;
296 if (route->path.origin.adv_router != lsa->header->adv_router)
297 continue;
298
299 if (IS_OSPF6_DEBUG_ASBR)
300 {
301 prefix2str (&route->prefix, buf, sizeof (buf));
302 zlog_info ("AS-External route remove: %s", buf);
303 }
304 ospf6_route_remove (route, ospf6->route_table);
305 }
306}
307
308void
309ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
310{
311 char buf[64];
312 struct ospf6_lsa *lsa;
313 u_int16_t type;
314 u_int32_t router;
315
316 if (IS_OSPF6_DEBUG_ASBR)
317 {
318 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
319 zlog_info ("New ASBR %s found", buf);
320 }
321
322 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
323 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
324 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
325 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
326 {
327 if (! OSPF6_LSA_IS_MAXAGE (lsa))
328 ospf6_asbr_lsa_add (lsa);
329 }
330
331 if (IS_OSPF6_DEBUG_ASBR)
332 {
333 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
334 zlog_info ("Calculation for new ASBR %s done", buf);
335 }
336}
337
338void
339ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
340{
341 char buf[64];
342 struct ospf6_lsa *lsa;
343 u_int16_t type;
344 u_int32_t router;
345
346 if (IS_OSPF6_DEBUG_ASBR)
347 {
348 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
349 zlog_info ("ASBR %s disappeared", buf);
350 }
351
352 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
353 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
354 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
355 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
356 ospf6_asbr_lsa_remove (lsa);
357
358 if (IS_OSPF6_DEBUG_ASBR)
359 {
360 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
361 zlog_info ("Calculation for old ASBR %s done", buf);
362 }
363}
364
365
366
paul718e3742002-12-13 20:15:29 +0000367/* redistribute function */
hasso508e53e2004-05-18 18:57:06 +0000368
paul718e3742002-12-13 20:15:29 +0000369void
370ospf6_asbr_routemap_set (int type, char *mapname)
371{
hasso508e53e2004-05-18 18:57:06 +0000372 if (ospf6->rmap[type].name)
373 free (ospf6->rmap[type].name);
374 ospf6->rmap[type].name = strdup (mapname);
375 ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
paul718e3742002-12-13 20:15:29 +0000376}
377
378void
379ospf6_asbr_routemap_unset (int type)
380{
hasso508e53e2004-05-18 18:57:06 +0000381 if (ospf6->rmap[type].name)
382 free (ospf6->rmap[type].name);
383 ospf6->rmap[type].name = NULL;
384 ospf6->rmap[type].map = NULL;
paul718e3742002-12-13 20:15:29 +0000385}
386
387void
388ospf6_asbr_routemap_update ()
389{
hasso508e53e2004-05-18 18:57:06 +0000390 int type;
391
392 if (ospf6 == NULL)
393 return;
394
395 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000396 {
hasso508e53e2004-05-18 18:57:06 +0000397 if (ospf6->rmap[type].name)
398 ospf6->rmap[type].map =
399 route_map_lookup_by_name (ospf6->rmap[type].name);
paul718e3742002-12-13 20:15:29 +0000400 else
hasso508e53e2004-05-18 18:57:06 +0000401 ospf6->rmap[type].map = NULL;
402 }
403}
404
405int
406ospf6_asbr_is_asbr (struct ospf6 *o)
407{
408 return o->external_table->count;
409}
410
411void
412ospf6_asbr_redistribute_set (int type)
413{
414 ospf6_zebra_redistribute (type);
415}
416
417void
418ospf6_asbr_redistribute_unset (int type)
419{
420 struct ospf6_route *route;
421 struct ospf6_external_info *info;
422
423 ospf6_zebra_no_redistribute (type);
424
425 for (route = ospf6_route_head (ospf6->external_table); route;
426 route = ospf6_route_next (route))
427 {
428 info = route->route_option;
429 if (info->type != type)
430 continue;
431
432 ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
433 &route->prefix);
434 }
435}
436
437void
438ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
439 u_int nexthop_num, struct in6_addr *nexthop)
440{
441 int ret;
442 struct ospf6_route troute;
443 struct ospf6_external_info tinfo;
444 struct ospf6_route *route, *match;
445 struct ospf6_external_info *info;
446 struct prefix prefix_id;
447 struct route_node *node;
448 char pbuf[64], ibuf[16];
449 listnode lnode;
450 struct ospf6_area *oa;
451
452 if (! ospf6_zebra_is_redistribute (type))
453 return;
454
455 if (IS_OSPF6_DEBUG_ASBR)
456 {
457 prefix2str (prefix, pbuf, sizeof (pbuf));
458 zlog_info ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
459 }
460
461 /* if route-map was specified but not found, do not advertise */
462 if (ospf6->rmap[type].name)
463 {
464 if (ospf6->rmap[type].map == NULL)
465 ospf6_asbr_routemap_update ();
466 if (ospf6->rmap[type].map == NULL)
467 {
468 zlog_warn ("route-map \"%s\" not found, suppress redistributing",
469 ospf6->rmap[type].name);
470 return;
471 }
472 }
473
474 /* apply route-map */
475 if (ospf6->rmap[type].map)
476 {
477 memset (&troute, 0, sizeof (troute));
478 memset (&tinfo, 0, sizeof (tinfo));
479 troute.route_option = &tinfo;
480
481 ret = route_map_apply (ospf6->rmap[type].map, prefix,
482 RMAP_OSPF6, &troute);
483 if (ret != RMAP_MATCH)
484 {
485 if (IS_OSPF6_DEBUG_ASBR)
486 zlog_info ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
487 return;
488 }
489 }
490
491 match = ospf6_route_lookup (prefix, ospf6->external_table);
492 if (match)
493 {
494 info = match->route_option;
495
496 /* copy result of route-map */
497 if (ospf6->rmap[type].map)
498 {
499 if (troute.path.metric_type)
500 match->path.metric_type = troute.path.metric_type;
501 if (troute.path.cost)
502 match->path.cost = troute.path.cost;
503 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
504 memcpy (&info->forwarding, &tinfo.forwarding,
505 sizeof (struct in6_addr));
506 }
507
508 info->type = type;
509 match->nexthop[0].ifindex = ifindex;
510 if (nexthop_num && nexthop)
511 memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
512
513 /* create/update binding in external_id_table */
514 prefix_id.family = AF_INET;
515 prefix_id.prefixlen = 32;
516 prefix_id.u.prefix4.s_addr = htonl (info->id);
517 node = route_node_get (ospf6->external_id_table, &prefix_id);
518 node->info = match;
519
520 if (IS_OSPF6_DEBUG_ASBR)
521 {
522 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
523 zlog_info ("Advertise as AS-External Id:%s", ibuf);
524 }
525
hasso3b687352004-08-19 06:56:53 +0000526 match->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000527 ospf6_as_external_lsa_originate (match);
hasso508e53e2004-05-18 18:57:06 +0000528 return;
529 }
530
531 /* create new entry */
532 route = ospf6_route_create ();
533 route->type = OSPF6_DEST_TYPE_NETWORK;
534 memcpy (&route->prefix, prefix, sizeof (struct prefix));
535
536 info = (struct ospf6_external_info *)
537 XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
538 memset (info, 0, sizeof (struct ospf6_external_info));
539 route->route_option = info;
540 info->id = ospf6->external_id++;
541
542 /* copy result of route-map */
543 if (ospf6->rmap[type].map)
544 {
545 if (troute.path.metric_type)
546 route->path.metric_type = troute.path.metric_type;
547 if (troute.path.cost)
548 route->path.cost = troute.path.cost;
549 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
550 memcpy (&info->forwarding, &tinfo.forwarding,
551 sizeof (struct in6_addr));
552 }
553
554 info->type = type;
555 route->nexthop[0].ifindex = ifindex;
556 if (nexthop_num && nexthop)
557 memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
558
559 /* create/update binding in external_id_table */
560 prefix_id.family = AF_INET;
561 prefix_id.prefixlen = 32;
562 prefix_id.u.prefix4.s_addr = htonl (info->id);
563 node = route_node_get (ospf6->external_id_table, &prefix_id);
564 node->info = route;
565
566 route = ospf6_route_add (route, ospf6->external_table);
567 route->route_option = info;
568
569 if (IS_OSPF6_DEBUG_ASBR)
570 {
571 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
572 zlog_info ("Advertise as AS-External Id:%s", ibuf);
573 }
574
hasso3b687352004-08-19 06:56:53 +0000575 route->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000576 ospf6_as_external_lsa_originate (route);
hasso508e53e2004-05-18 18:57:06 +0000577
578 /* Router-Bit (ASBR Flag) may have to be updated */
579 for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode))
580 {
581 oa = (struct ospf6_area *) getdata (lnode);
582 OSPF6_ROUTER_LSA_SCHEDULE (oa);
583 }
584}
585
586void
587ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
588{
589 struct ospf6_route *match;
590 struct ospf6_external_info *info = NULL;
591 struct route_node *node;
592 struct ospf6_lsa *lsa;
593 struct prefix prefix_id;
594 char pbuf[64], ibuf[16];
595 listnode lnode;
596 struct ospf6_area *oa;
597
598 match = ospf6_route_lookup (prefix, ospf6->external_table);
599 if (match == NULL)
600 {
601 if (IS_OSPF6_DEBUG_ASBR)
602 {
603 prefix2str (prefix, pbuf, sizeof (pbuf));
604 zlog_info ("No such route %s to withdraw", pbuf);
605 }
606 return;
607 }
608
609 info = match->route_option;
610 assert (info);
611
612 if (info->type != type)
613 {
614 if (IS_OSPF6_DEBUG_ASBR)
615 {
616 prefix2str (prefix, pbuf, sizeof (pbuf));
617 zlog_info ("Original protocol mismatch: %s", pbuf);
618 }
619 return;
620 }
621
622 if (IS_OSPF6_DEBUG_ASBR)
623 {
624 prefix2str (prefix, pbuf, sizeof (pbuf));
625 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
626 zlog_info ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
627 }
628
629 lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
630 htonl (info->id), ospf6->router_id, ospf6->lsdb);
631 if (lsa)
hasso6452df02004-08-15 05:52:07 +0000632 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000633
634 /* remove binding in external_id_table */
635 prefix_id.family = AF_INET;
636 prefix_id.prefixlen = 32;
637 prefix_id.u.prefix4.s_addr = htonl (info->id);
638 node = route_node_lookup (ospf6->external_id_table, &prefix_id);
639 assert (node);
640 node->info = NULL;
641 route_unlock_node (node);
642
643 ospf6_route_remove (match, ospf6->external_table);
644 XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
645
646 /* Router-Bit (ASBR Flag) may have to be updated */
647 for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode))
648 {
649 oa = (struct ospf6_area *) getdata (lnode);
650 OSPF6_ROUTER_LSA_SCHEDULE (oa);
paul718e3742002-12-13 20:15:29 +0000651 }
652}
653
654DEFUN (ospf6_redistribute,
655 ospf6_redistribute_cmd,
656 "redistribute (static|kernel|connected|ripng|bgp)",
657 "Redistribute\n"
658 "Static route\n"
659 "Kernel route\n"
660 "Connected route\n"
661 "RIPng route\n"
662 "BGP route\n"
663 )
664{
665 int type = 0;
666
667 if (strncmp (argv[0], "sta", 3) == 0)
668 type = ZEBRA_ROUTE_STATIC;
669 else if (strncmp (argv[0], "ker", 3) == 0)
670 type = ZEBRA_ROUTE_KERNEL;
671 else if (strncmp (argv[0], "con", 3) == 0)
672 type = ZEBRA_ROUTE_CONNECT;
673 else if (strncmp (argv[0], "rip", 3) == 0)
674 type = ZEBRA_ROUTE_RIPNG;
675 else if (strncmp (argv[0], "bgp", 3) == 0)
676 type = ZEBRA_ROUTE_BGP;
677
hasso508e53e2004-05-18 18:57:06 +0000678 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000679 ospf6_asbr_routemap_unset (type);
hasso508e53e2004-05-18 18:57:06 +0000680 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000681 return CMD_SUCCESS;
682}
683
684DEFUN (ospf6_redistribute_routemap,
685 ospf6_redistribute_routemap_cmd,
686 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
687 "Redistribute\n"
688 "Static routes\n"
689 "Kernel route\n"
690 "Connected route\n"
691 "RIPng route\n"
692 "BGP route\n"
693 "Route map reference\n"
694 "Route map name\n"
695 )
696{
697 int type = 0;
698
699 if (strncmp (argv[0], "sta", 3) == 0)
700 type = ZEBRA_ROUTE_STATIC;
701 else if (strncmp (argv[0], "ker", 3) == 0)
702 type = ZEBRA_ROUTE_KERNEL;
703 else if (strncmp (argv[0], "con", 3) == 0)
704 type = ZEBRA_ROUTE_CONNECT;
705 else if (strncmp (argv[0], "rip", 3) == 0)
706 type = ZEBRA_ROUTE_RIPNG;
707 else if (strncmp (argv[0], "bgp", 3) == 0)
708 type = ZEBRA_ROUTE_BGP;
709
hasso508e53e2004-05-18 18:57:06 +0000710 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000711 ospf6_asbr_routemap_set (type, argv[1]);
hasso508e53e2004-05-18 18:57:06 +0000712 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000713 return CMD_SUCCESS;
714}
715
716DEFUN (no_ospf6_redistribute,
717 no_ospf6_redistribute_cmd,
718 "no redistribute (static|kernel|connected|ripng|bgp)",
719 NO_STR
720 "Redistribute\n"
721 "Static route\n"
722 "Kernel route\n"
723 "Connected route\n"
724 "RIPng route\n"
725 "BGP route\n"
726 )
727{
728 int type = 0;
paul718e3742002-12-13 20:15:29 +0000729
730 if (strncmp (argv[0], "sta", 3) == 0)
731 type = ZEBRA_ROUTE_STATIC;
732 else if (strncmp (argv[0], "ker", 3) == 0)
733 type = ZEBRA_ROUTE_KERNEL;
734 else if (strncmp (argv[0], "con", 3) == 0)
735 type = ZEBRA_ROUTE_CONNECT;
736 else if (strncmp (argv[0], "rip", 3) == 0)
737 type = ZEBRA_ROUTE_RIPNG;
738 else if (strncmp (argv[0], "bgp", 3) == 0)
739 type = ZEBRA_ROUTE_BGP;
740
hasso508e53e2004-05-18 18:57:06 +0000741 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000742 ospf6_asbr_routemap_unset (type);
743
paul718e3742002-12-13 20:15:29 +0000744 return CMD_SUCCESS;
745}
746
paul718e3742002-12-13 20:15:29 +0000747int
748ospf6_redistribute_config_write (struct vty *vty)
749{
hasso508e53e2004-05-18 18:57:06 +0000750 int type;
paul718e3742002-12-13 20:15:29 +0000751
hasso508e53e2004-05-18 18:57:06 +0000752 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000753 {
hasso508e53e2004-05-18 18:57:06 +0000754 if (type == ZEBRA_ROUTE_OSPF6)
755 continue;
756 if (! ospf6_zebra_is_redistribute (type))
paul718e3742002-12-13 20:15:29 +0000757 continue;
758
hasso508e53e2004-05-18 18:57:06 +0000759 if (ospf6->rmap[type].name)
paul718e3742002-12-13 20:15:29 +0000760 vty_out (vty, " redistribute %s route-map %s%s",
hasso049207c2004-08-04 20:02:13 +0000761 ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
paul718e3742002-12-13 20:15:29 +0000762 else
763 vty_out (vty, " redistribute %s%s",
hasso049207c2004-08-04 20:02:13 +0000764 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000765 }
766
767 return 0;
768}
769
770void
771ospf6_redistribute_show_config (struct vty *vty)
772{
hasso508e53e2004-05-18 18:57:06 +0000773 int type;
774 int nroute[ZEBRA_ROUTE_MAX];
775 int total;
776 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000777 struct ospf6_external_info *info;
paul718e3742002-12-13 20:15:29 +0000778
hasso508e53e2004-05-18 18:57:06 +0000779 total = 0;
780 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
781 nroute[type] = 0;
782 for (route = ospf6_route_head (ospf6->external_table); route;
783 route = ospf6_route_next (route))
paul718e3742002-12-13 20:15:29 +0000784 {
hasso508e53e2004-05-18 18:57:06 +0000785 info = route->route_option;
786 nroute[info->type]++;
787 total++;
paul718e3742002-12-13 20:15:29 +0000788 }
789
hasso049207c2004-08-04 20:02:13 +0000790 vty_out (vty, "Redistributing External Routes from:%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000791 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000792 {
hasso508e53e2004-05-18 18:57:06 +0000793 if (type == ZEBRA_ROUTE_OSPF6)
794 continue;
795 if (! ospf6_zebra_is_redistribute (type))
hassoe26bbeb2003-05-25 21:39:29 +0000796 continue;
797
hasso508e53e2004-05-18 18:57:06 +0000798 if (ospf6->rmap[type].name)
799 vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
800 ZROUTE_NAME (type), ospf6->rmap[type].name,
801 (ospf6->rmap[type].map ? "" : " (not found !)"),
hasso049207c2004-08-04 20:02:13 +0000802 VNL);
paul718e3742002-12-13 20:15:29 +0000803 else
hasso508e53e2004-05-18 18:57:06 +0000804 vty_out (vty, " %d: %s%s", nroute[type],
hasso049207c2004-08-04 20:02:13 +0000805 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000806 }
hasso049207c2004-08-04 20:02:13 +0000807 vty_out (vty, "Total %d routes%s", total, VNL);
hasso508e53e2004-05-18 18:57:06 +0000808}
paul718e3742002-12-13 20:15:29 +0000809
paul718e3742002-12-13 20:15:29 +0000810
hasso508e53e2004-05-18 18:57:06 +0000811
812/* Routemap Functions */
813route_map_result_t
814ospf6_routemap_rule_match_address_prefixlist (void *rule,
815 struct prefix *prefix,
816 route_map_object_t type,
817 void *object)
818{
819 struct prefix_list *plist;
paul718e3742002-12-13 20:15:29 +0000820
hasso508e53e2004-05-18 18:57:06 +0000821 if (type != RMAP_OSPF6)
822 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000823
hasso508e53e2004-05-18 18:57:06 +0000824 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
825 if (plist == NULL)
826 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000827
hasso508e53e2004-05-18 18:57:06 +0000828 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
829 RMAP_NOMATCH : RMAP_MATCH);
830}
paul718e3742002-12-13 20:15:29 +0000831
hasso508e53e2004-05-18 18:57:06 +0000832void *
833ospf6_routemap_rule_match_address_prefixlist_compile (char *arg)
834{
835 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000836}
837
838void
hasso508e53e2004-05-18 18:57:06 +0000839ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000840{
hasso508e53e2004-05-18 18:57:06 +0000841 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
842}
paul718e3742002-12-13 20:15:29 +0000843
hasso508e53e2004-05-18 18:57:06 +0000844struct route_map_rule_cmd
845ospf6_routemap_rule_match_address_prefixlist_cmd =
846{
847 "ipv6 address prefix-list",
848 ospf6_routemap_rule_match_address_prefixlist,
849 ospf6_routemap_rule_match_address_prefixlist_compile,
850 ospf6_routemap_rule_match_address_prefixlist_free,
851};
hassoe26bbeb2003-05-25 21:39:29 +0000852
hasso508e53e2004-05-18 18:57:06 +0000853route_map_result_t
854ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
855 route_map_object_t type, void *object)
856{
857 char *metric_type = rule;
858 struct ospf6_route *route = object;
hassoe26bbeb2003-05-25 21:39:29 +0000859
hasso508e53e2004-05-18 18:57:06 +0000860 if (type != RMAP_OSPF6)
861 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000862
hasso508e53e2004-05-18 18:57:06 +0000863 if (strcmp (metric_type, "type-2") == 0)
864 route->path.metric_type = 2;
paul718e3742002-12-13 20:15:29 +0000865 else
hasso508e53e2004-05-18 18:57:06 +0000866 route->path.metric_type = 1;
paul718e3742002-12-13 20:15:29 +0000867
hasso508e53e2004-05-18 18:57:06 +0000868 return RMAP_OKAY;
869}
paul718e3742002-12-13 20:15:29 +0000870
hasso508e53e2004-05-18 18:57:06 +0000871void *
872ospf6_routemap_rule_set_metric_type_compile (char *arg)
873{
874 if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
875 return NULL;
876 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000877}
878
879void
hasso508e53e2004-05-18 18:57:06 +0000880ospf6_routemap_rule_set_metric_type_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000881{
hasso508e53e2004-05-18 18:57:06 +0000882 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
883}
paul718e3742002-12-13 20:15:29 +0000884
hasso508e53e2004-05-18 18:57:06 +0000885struct route_map_rule_cmd
886ospf6_routemap_rule_set_metric_type_cmd =
887{
888 "metric-type",
889 ospf6_routemap_rule_set_metric_type,
890 ospf6_routemap_rule_set_metric_type_compile,
891 ospf6_routemap_rule_set_metric_type_free,
892};
paul718e3742002-12-13 20:15:29 +0000893
hasso508e53e2004-05-18 18:57:06 +0000894route_map_result_t
895ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
896 route_map_object_t type, void *object)
897{
898 char *metric = rule;
899 struct ospf6_route *route = object;
paul718e3742002-12-13 20:15:29 +0000900
hasso508e53e2004-05-18 18:57:06 +0000901 if (type != RMAP_OSPF6)
902 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000903
hasso508e53e2004-05-18 18:57:06 +0000904 route->path.cost = atoi (metric);
905 return RMAP_OKAY;
906}
paul718e3742002-12-13 20:15:29 +0000907
hasso508e53e2004-05-18 18:57:06 +0000908void *
909ospf6_routemap_rule_set_metric_compile (char *arg)
910{
911 u_int32_t metric;
912 char *endp;
913 metric = strtoul (arg, &endp, 0);
914 if (metric > LS_INFINITY || *endp != '\0')
915 return NULL;
916 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000917}
918
919void
hasso508e53e2004-05-18 18:57:06 +0000920ospf6_routemap_rule_set_metric_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000921{
hasso508e53e2004-05-18 18:57:06 +0000922 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
923}
924
925struct route_map_rule_cmd
926ospf6_routemap_rule_set_metric_cmd =
927{
928 "metric",
929 ospf6_routemap_rule_set_metric,
930 ospf6_routemap_rule_set_metric_compile,
931 ospf6_routemap_rule_set_metric_free,
932};
933
934route_map_result_t
935ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
936 route_map_object_t type, void *object)
937{
938 char *forwarding = rule;
939 struct ospf6_route *route = object;
940 struct ospf6_external_info *info = route->route_option;
941
942 if (type != RMAP_OSPF6)
943 return RMAP_OKAY;
944
945 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
946 {
947 memset (&info->forwarding, 0, sizeof (struct in6_addr));
948 return RMAP_ERROR;
949 }
950
951 return RMAP_OKAY;
952}
953
954void *
955ospf6_routemap_rule_set_forwarding_compile (char *arg)
956{
957 struct in6_addr a;
958 if (inet_pton (AF_INET6, arg, &a) != 1)
959 return NULL;
960 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
961}
962
963void
964ospf6_routemap_rule_set_forwarding_free (void *rule)
965{
966 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
967}
968
969struct route_map_rule_cmd
970ospf6_routemap_rule_set_forwarding_cmd =
971{
972 "forwarding-address",
973 ospf6_routemap_rule_set_forwarding,
974 ospf6_routemap_rule_set_forwarding_compile,
975 ospf6_routemap_rule_set_forwarding_free,
976};
977
978int
979route_map_command_status (struct vty *vty, int ret)
980{
981 if (! ret)
982 return CMD_SUCCESS;
983
984 switch (ret)
985 {
986 case RMAP_RULE_MISSING:
hasso049207c2004-08-04 20:02:13 +0000987 vty_out (vty, "Can't find rule.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000988 break;
989 case RMAP_COMPILE_ERROR:
hasso049207c2004-08-04 20:02:13 +0000990 vty_out (vty, "Argument is malformed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000991 break;
992 default:
hasso049207c2004-08-04 20:02:13 +0000993 vty_out (vty, "route-map add set failed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000994 break;
995 }
996 return CMD_WARNING;
997}
998
999/* add "match address" */
1000DEFUN (ospf6_routemap_match_address_prefixlist,
1001 ospf6_routemap_match_address_prefixlist_cmd,
1002 "match ipv6 address prefix-list WORD",
1003 "Match values\n"
1004 IPV6_STR
1005 "Match address of route\n"
1006 "Match entries of prefix-lists\n"
1007 "IPv6 prefix-list name\n")
1008{
1009 int ret = route_map_add_match ((struct route_map_index *) vty->index,
1010 "ipv6 address prefix-list", argv[0]);
1011 return route_map_command_status (vty, ret);
1012}
1013
1014/* delete "match address" */
1015DEFUN (ospf6_routemap_no_match_address_prefixlist,
1016 ospf6_routemap_no_match_address_prefixlist_cmd,
1017 "no match ipv6 address prefix-list WORD",
1018 NO_STR
1019 "Match values\n"
1020 IPV6_STR
1021 "Match address of route\n"
1022 "Match entries of prefix-lists\n"
1023 "IPv6 prefix-list name\n")
1024{
1025 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1026 "ipv6 address prefix-list", argv[0]);
1027 return route_map_command_status (vty, ret);
1028}
1029
1030/* add "set metric-type" */
1031DEFUN (ospf6_routemap_set_metric_type,
1032 ospf6_routemap_set_metric_type_cmd,
1033 "set metric-type (type-1|type-2)",
1034 "Set value\n"
1035 "Type of metric\n"
1036 "OSPF6 external type 1 metric\n"
1037 "OSPF6 external type 2 metric\n")
1038{
1039 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1040 "metric-type", argv[0]);
1041 return route_map_command_status (vty, ret);
1042}
1043
1044/* delete "set metric-type" */
1045DEFUN (ospf6_routemap_no_set_metric_type,
1046 ospf6_routemap_no_set_metric_type_cmd,
1047 "no set metric-type (type-1|type-2)",
1048 NO_STR
1049 "Set value\n"
1050 "Type of metric\n"
1051 "OSPF6 external type 1 metric\n"
1052 "OSPF6 external type 2 metric\n")
1053{
1054 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1055 "metric-type", argv[0]);
1056 return route_map_command_status (vty, ret);
1057}
1058
1059/* add "set metric" */
1060DEFUN (set_metric,
1061 set_metric_cmd,
1062 "set metric <0-4294967295>",
1063 "Set value\n"
1064 "Metric value\n"
1065 "Metric value\n")
1066{
1067 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1068 "metric", argv[0]);
1069 return route_map_command_status (vty, ret);
1070}
1071
1072/* delete "set metric" */
1073DEFUN (no_set_metric,
1074 no_set_metric_cmd,
1075 "no set metric <0-4294967295>",
1076 NO_STR
1077 "Set value\n"
1078 "Metric\n"
1079 "METRIC value\n")
1080{
1081 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1082 "metric", argv[0]);
1083 return route_map_command_status (vty, ret);
1084}
1085
1086/* add "set forwarding-address" */
1087DEFUN (ospf6_routemap_set_forwarding,
1088 ospf6_routemap_set_forwarding_cmd,
1089 "set forwarding-address X:X::X:X",
1090 "Set value\n"
1091 "Forwarding Address\n"
1092 "IPv6 Address\n")
1093{
1094 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1095 "forwarding-address", argv[0]);
1096 return route_map_command_status (vty, ret);
1097}
1098
1099/* delete "set forwarding-address" */
1100DEFUN (ospf6_routemap_no_set_forwarding,
1101 ospf6_routemap_no_set_forwarding_cmd,
1102 "no set forwarding-address X:X::X:X",
1103 NO_STR
1104 "Set value\n"
1105 "Forwarding Address\n"
1106 "IPv6 Address\n")
1107{
1108 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1109 "forwarding-address", argv[0]);
1110 return route_map_command_status (vty, ret);
1111}
1112
1113void
1114ospf6_routemap_init ()
1115{
1116 route_map_init ();
1117 route_map_init_vty ();
1118 route_map_add_hook (ospf6_asbr_routemap_update);
1119 route_map_delete_hook (ospf6_asbr_routemap_update);
1120
1121 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
1122 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
1123 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
1124 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
1125
1126 /* Match address prefix-list */
1127 install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
1128 install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
1129
1130 /* ASE Metric Type (e.g. Type-1/Type-2) */
1131 install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
1132 install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
1133
1134 /* ASE Metric */
1135 install_element (RMAP_NODE, &set_metric_cmd);
1136 install_element (RMAP_NODE, &no_set_metric_cmd);
1137
1138 /* ASE Metric */
1139 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
1140 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
1141}
1142
1143
1144/* Display functions */
1145int
1146ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
1147{
1148 struct ospf6_as_external_lsa *external;
paul718e3742002-12-13 20:15:29 +00001149 char buf[64];
hasso508e53e2004-05-18 18:57:06 +00001150 struct in6_addr in6, *forwarding;
paul718e3742002-12-13 20:15:29 +00001151
1152 assert (lsa->header);
hasso508e53e2004-05-18 18:57:06 +00001153 external = (struct ospf6_as_external_lsa *)
1154 OSPF6_LSA_HEADER_END (lsa->header);
paul718e3742002-12-13 20:15:29 +00001155
1156 /* bits */
hasso508e53e2004-05-18 18:57:06 +00001157 snprintf (buf, sizeof (buf), "%c%c%c",
1158 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
1159 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
1160 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
paul718e3742002-12-13 20:15:29 +00001161
hasso049207c2004-08-04 20:02:13 +00001162 vty_out (vty, " Bits: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +00001163 vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
hasso049207c2004-08-04 20:02:13 +00001164 VNL);
paul718e3742002-12-13 20:15:29 +00001165
hasso508e53e2004-05-18 18:57:06 +00001166 ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1167 buf, sizeof (buf));
1168 vty_out (vty, " Prefix Options: %s%s", buf,
hasso049207c2004-08-04 20:02:13 +00001169 VNL);
paul718e3742002-12-13 20:15:29 +00001170
1171 vty_out (vty, " Referenced LSType: %d%s",
hasso508e53e2004-05-18 18:57:06 +00001172 ntohs (external->prefix.prefix_refer_lstype),
hasso049207c2004-08-04 20:02:13 +00001173 VNL);
paul718e3742002-12-13 20:15:29 +00001174
hasso508e53e2004-05-18 18:57:06 +00001175 ospf6_prefix_in6_addr (&in6, &external->prefix);
paul718e3742002-12-13 20:15:29 +00001176 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
hasso508e53e2004-05-18 18:57:06 +00001177 vty_out (vty, " Prefix: %s/%d%s", buf,
hasso049207c2004-08-04 20:02:13 +00001178 external->prefix.prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +00001179
1180 /* Forwarding-Address */
1181 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
1182 {
hasso508e53e2004-05-18 18:57:06 +00001183 forwarding = (struct in6_addr *)
1184 ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
1185 OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
1186 inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +00001187 vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
paul718e3742002-12-13 20:15:29 +00001188 }
1189
1190 return 0;
1191}
1192
1193void
hasso508e53e2004-05-18 18:57:06 +00001194ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +00001195{
hasso508e53e2004-05-18 18:57:06 +00001196 struct ospf6_external_info *info = route->route_option;
1197 char prefix[64], id[16], forwarding[64];
1198 u_int32_t tmp_id;
1199
1200 prefix2str (&route->prefix, prefix, sizeof (prefix));
1201 tmp_id = ntohl (info->id);
1202 inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
1203 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
1204 inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
1205 else
1206 snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
1207 route->nexthop[0].ifindex);
1208
1209 vty_out (vty, "%s %-32s %-15s type-%d %5lu %s%s",
1210 ZROUTE_ABNAME (info->type),
1211 prefix, id, route->path.metric_type,
1212 (u_long) (route->path.metric_type == 2 ?
1213 route->path.cost_e2 : route->path.cost),
hasso049207c2004-08-04 20:02:13 +00001214 forwarding, VNL);
paul718e3742002-12-13 20:15:29 +00001215}
1216
hasso508e53e2004-05-18 18:57:06 +00001217DEFUN (show_ipv6_ospf6_redistribute,
1218 show_ipv6_ospf6_redistribute_cmd,
1219 "show ipv6 ospf6 redistribute",
paul718e3742002-12-13 20:15:29 +00001220 SHOW_STR
1221 IP6_STR
paul718e3742002-12-13 20:15:29 +00001222 OSPF6_STR
1223 "redistributing External information\n"
1224 )
1225{
hasso508e53e2004-05-18 18:57:06 +00001226 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +00001227
hasso508e53e2004-05-18 18:57:06 +00001228 ospf6_redistribute_show_config (vty);
1229
1230 for (route = ospf6_route_head (ospf6->external_table); route;
1231 route = ospf6_route_next (route))
1232 ospf6_asbr_external_route_show (vty, route);
1233
paul718e3742002-12-13 20:15:29 +00001234 return CMD_SUCCESS;
1235}
1236
hasso6452df02004-08-15 05:52:07 +00001237struct ospf6_lsa_handler as_external_handler =
hasso508e53e2004-05-18 18:57:06 +00001238{
hasso6452df02004-08-15 05:52:07 +00001239 OSPF6_LSTYPE_AS_EXTERNAL,
1240 "AS-External",
1241 ospf6_as_external_lsa_show
1242};
hasso508e53e2004-05-18 18:57:06 +00001243
paul718e3742002-12-13 20:15:29 +00001244void
1245ospf6_asbr_init ()
1246{
hasso508e53e2004-05-18 18:57:06 +00001247 ospf6_routemap_init ();
paul718e3742002-12-13 20:15:29 +00001248
hasso6452df02004-08-15 05:52:07 +00001249 ospf6_install_lsa_handler (&as_external_handler);
paul718e3742002-12-13 20:15:29 +00001250
hasso508e53e2004-05-18 18:57:06 +00001251 install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
1252 install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
1253
paul718e3742002-12-13 20:15:29 +00001254 install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
1255 install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
1256 install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
1257}
1258
1259
hasso508e53e2004-05-18 18:57:06 +00001260DEFUN (debug_ospf6_asbr,
1261 debug_ospf6_asbr_cmd,
1262 "debug ospf6 asbr",
1263 DEBUG_STR
1264 OSPF6_STR
1265 "Debug OSPFv3 ASBR function\n"
1266 )
1267{
1268 OSPF6_DEBUG_ASBR_ON ();
1269 return CMD_SUCCESS;
1270}
1271
1272DEFUN (no_debug_ospf6_asbr,
1273 no_debug_ospf6_asbr_cmd,
1274 "no debug ospf6 asbr",
1275 NO_STR
1276 DEBUG_STR
1277 OSPF6_STR
1278 "Debug OSPFv3 ASBR function\n"
1279 )
1280{
1281 OSPF6_DEBUG_ASBR_OFF ();
1282 return CMD_SUCCESS;
1283}
1284
1285int
1286config_write_ospf6_debug_asbr (struct vty *vty)
1287{
1288 if (IS_OSPF6_DEBUG_ASBR)
hasso049207c2004-08-04 20:02:13 +00001289 vty_out (vty, "debug ospf6 asbr%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001290 return 0;
1291}
1292
1293void
1294install_element_ospf6_debug_asbr ()
1295{
1296 install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
1297 install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
1298 install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
1299 install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
1300}
1301
1302