blob: 3352465cfa3e594f75e01a3cff8c66fc3a132d67 [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
hassoccb59b12004-08-25 09:10:37 +0000195 ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);
hasso6452df02004-08-15 05:52:07 +0000196 asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
hasso508e53e2004-05-18 18:57:06 +0000197 if (asbr_entry == NULL)
198 {
199 if (IS_OSPF6_DEBUG_ASBR)
200 {
201 prefix2str (&asbr_id, buf, sizeof (buf));
202 zlog_info ("ASBR entry not found: %s", buf);
203 }
204 return;
205 }
206
207 route = ospf6_route_create ();
208 route->type = OSPF6_DEST_TYPE_NETWORK;
209 route->prefix.family = AF_INET6;
210 route->prefix.prefixlen = external->prefix.prefix_length;
211 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
212
213 route->path.area_id = asbr_entry->path.area_id;
214 route->path.origin.type = lsa->header->type;
215 route->path.origin.id = lsa->header->id;
216 route->path.origin.adv_router = lsa->header->adv_router;
217
218 route->path.prefix_options = external->prefix.prefix_options;
219 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
220 {
221 route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
222 route->path.metric_type = 2;
223 route->path.cost = asbr_entry->path.cost;
224 route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
225 }
226 else
227 {
228 route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
229 route->path.metric_type = 1;
230 route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
231 route->path.cost_e2 = 0;
232 }
233
234 for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
235 ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
236
237 if (IS_OSPF6_DEBUG_ASBR)
238 {
239 prefix2str (&route->prefix, buf, sizeof (buf));
240 zlog_info ("AS-External route add: %s", buf);
241 }
242
243 ospf6_route_add (route, ospf6->route_table);
244}
245
246void
247ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
248{
249 struct ospf6_as_external_lsa *external;
250 struct prefix prefix;
251 struct ospf6_route *route;
252 char buf[64];
253
254 external = (struct ospf6_as_external_lsa *)
255 OSPF6_LSA_HEADER_END (lsa->header);
256
257 if (IS_OSPF6_DEBUG_ASBR)
258 zlog_info ("Withdraw AS-External route for %s", lsa->name);
259
260 if (lsa->header->adv_router == ospf6->router_id)
261 {
262 if (IS_OSPF6_DEBUG_ASBR)
263 zlog_info ("Ignore self-originated AS-External-LSA");
264 return;
265 }
266
267 memset (&prefix, 0, sizeof (struct prefix));
268 prefix.family = AF_INET6;
269 prefix.prefixlen = external->prefix.prefix_length;
270 ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
271
272 route = ospf6_route_lookup (&prefix, ospf6->route_table);
273 if (route == NULL)
274 {
275 if (IS_OSPF6_DEBUG_ASBR)
276 {
277 prefix2str (&prefix, buf, sizeof (buf));
278 zlog_info ("AS-External route %s not found", buf);
279 }
280 return;
281 }
282
283 for (ospf6_route_lock (route);
284 route && ospf6_route_is_prefix (&prefix, route);
285 route = ospf6_route_next (route))
286 {
287 if (route->type != OSPF6_DEST_TYPE_NETWORK)
288 continue;
289 if (route->path.origin.type != lsa->header->type)
290 continue;
291 if (route->path.origin.id != lsa->header->id)
292 continue;
293 if (route->path.origin.adv_router != lsa->header->adv_router)
294 continue;
295
296 if (IS_OSPF6_DEBUG_ASBR)
297 {
298 prefix2str (&route->prefix, buf, sizeof (buf));
299 zlog_info ("AS-External route remove: %s", buf);
300 }
301 ospf6_route_remove (route, ospf6->route_table);
302 }
303}
304
305void
306ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
307{
308 char buf[64];
309 struct ospf6_lsa *lsa;
310 u_int16_t type;
311 u_int32_t router;
312
313 if (IS_OSPF6_DEBUG_ASBR)
314 {
315 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
316 zlog_info ("New ASBR %s found", buf);
317 }
318
319 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
320 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
321 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
322 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
323 {
324 if (! OSPF6_LSA_IS_MAXAGE (lsa))
325 ospf6_asbr_lsa_add (lsa);
326 }
327
328 if (IS_OSPF6_DEBUG_ASBR)
329 {
330 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
331 zlog_info ("Calculation for new ASBR %s done", buf);
332 }
333}
334
335void
336ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
337{
338 char buf[64];
339 struct ospf6_lsa *lsa;
340 u_int16_t type;
341 u_int32_t router;
342
343 if (IS_OSPF6_DEBUG_ASBR)
344 {
345 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
346 zlog_info ("ASBR %s disappeared", buf);
347 }
348
349 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
350 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
351 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
352 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
353 ospf6_asbr_lsa_remove (lsa);
354
355 if (IS_OSPF6_DEBUG_ASBR)
356 {
357 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
358 zlog_info ("Calculation for old ASBR %s done", buf);
359 }
360}
361
362
363
paul718e3742002-12-13 20:15:29 +0000364/* redistribute function */
hasso508e53e2004-05-18 18:57:06 +0000365
paul718e3742002-12-13 20:15:29 +0000366void
367ospf6_asbr_routemap_set (int type, char *mapname)
368{
hasso508e53e2004-05-18 18:57:06 +0000369 if (ospf6->rmap[type].name)
370 free (ospf6->rmap[type].name);
371 ospf6->rmap[type].name = strdup (mapname);
372 ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
paul718e3742002-12-13 20:15:29 +0000373}
374
375void
376ospf6_asbr_routemap_unset (int type)
377{
hasso508e53e2004-05-18 18:57:06 +0000378 if (ospf6->rmap[type].name)
379 free (ospf6->rmap[type].name);
380 ospf6->rmap[type].name = NULL;
381 ospf6->rmap[type].map = NULL;
paul718e3742002-12-13 20:15:29 +0000382}
383
384void
385ospf6_asbr_routemap_update ()
386{
hasso508e53e2004-05-18 18:57:06 +0000387 int type;
388
389 if (ospf6 == NULL)
390 return;
391
392 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000393 {
hasso508e53e2004-05-18 18:57:06 +0000394 if (ospf6->rmap[type].name)
395 ospf6->rmap[type].map =
396 route_map_lookup_by_name (ospf6->rmap[type].name);
paul718e3742002-12-13 20:15:29 +0000397 else
hasso508e53e2004-05-18 18:57:06 +0000398 ospf6->rmap[type].map = NULL;
399 }
400}
401
402int
403ospf6_asbr_is_asbr (struct ospf6 *o)
404{
405 return o->external_table->count;
406}
407
408void
409ospf6_asbr_redistribute_set (int type)
410{
411 ospf6_zebra_redistribute (type);
412}
413
414void
415ospf6_asbr_redistribute_unset (int type)
416{
417 struct ospf6_route *route;
418 struct ospf6_external_info *info;
419
420 ospf6_zebra_no_redistribute (type);
421
422 for (route = ospf6_route_head (ospf6->external_table); route;
423 route = ospf6_route_next (route))
424 {
425 info = route->route_option;
426 if (info->type != type)
427 continue;
428
429 ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
430 &route->prefix);
431 }
432}
433
434void
435ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
436 u_int nexthop_num, struct in6_addr *nexthop)
437{
438 int ret;
439 struct ospf6_route troute;
440 struct ospf6_external_info tinfo;
441 struct ospf6_route *route, *match;
442 struct ospf6_external_info *info;
443 struct prefix prefix_id;
444 struct route_node *node;
445 char pbuf[64], ibuf[16];
446 listnode lnode;
447 struct ospf6_area *oa;
448
449 if (! ospf6_zebra_is_redistribute (type))
450 return;
451
452 if (IS_OSPF6_DEBUG_ASBR)
453 {
454 prefix2str (prefix, pbuf, sizeof (pbuf));
455 zlog_info ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
456 }
457
458 /* if route-map was specified but not found, do not advertise */
459 if (ospf6->rmap[type].name)
460 {
461 if (ospf6->rmap[type].map == NULL)
462 ospf6_asbr_routemap_update ();
463 if (ospf6->rmap[type].map == NULL)
464 {
465 zlog_warn ("route-map \"%s\" not found, suppress redistributing",
466 ospf6->rmap[type].name);
467 return;
468 }
469 }
470
471 /* apply route-map */
472 if (ospf6->rmap[type].map)
473 {
474 memset (&troute, 0, sizeof (troute));
475 memset (&tinfo, 0, sizeof (tinfo));
476 troute.route_option = &tinfo;
477
478 ret = route_map_apply (ospf6->rmap[type].map, prefix,
479 RMAP_OSPF6, &troute);
480 if (ret != RMAP_MATCH)
481 {
482 if (IS_OSPF6_DEBUG_ASBR)
483 zlog_info ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
484 return;
485 }
486 }
487
488 match = ospf6_route_lookup (prefix, ospf6->external_table);
489 if (match)
490 {
491 info = match->route_option;
492
493 /* copy result of route-map */
494 if (ospf6->rmap[type].map)
495 {
496 if (troute.path.metric_type)
497 match->path.metric_type = troute.path.metric_type;
498 if (troute.path.cost)
499 match->path.cost = troute.path.cost;
500 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
501 memcpy (&info->forwarding, &tinfo.forwarding,
502 sizeof (struct in6_addr));
503 }
504
505 info->type = type;
506 match->nexthop[0].ifindex = ifindex;
507 if (nexthop_num && nexthop)
508 memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
509
510 /* create/update binding in external_id_table */
511 prefix_id.family = AF_INET;
512 prefix_id.prefixlen = 32;
513 prefix_id.u.prefix4.s_addr = htonl (info->id);
514 node = route_node_get (ospf6->external_id_table, &prefix_id);
515 node->info = match;
516
517 if (IS_OSPF6_DEBUG_ASBR)
518 {
519 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
520 zlog_info ("Advertise as AS-External Id:%s", ibuf);
521 }
522
hasso3b687352004-08-19 06:56:53 +0000523 match->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000524 ospf6_as_external_lsa_originate (match);
hasso508e53e2004-05-18 18:57:06 +0000525 return;
526 }
527
528 /* create new entry */
529 route = ospf6_route_create ();
530 route->type = OSPF6_DEST_TYPE_NETWORK;
531 memcpy (&route->prefix, prefix, sizeof (struct prefix));
532
533 info = (struct ospf6_external_info *)
534 XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
535 memset (info, 0, sizeof (struct ospf6_external_info));
536 route->route_option = info;
537 info->id = ospf6->external_id++;
538
539 /* copy result of route-map */
540 if (ospf6->rmap[type].map)
541 {
542 if (troute.path.metric_type)
543 route->path.metric_type = troute.path.metric_type;
544 if (troute.path.cost)
545 route->path.cost = troute.path.cost;
546 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
547 memcpy (&info->forwarding, &tinfo.forwarding,
548 sizeof (struct in6_addr));
549 }
550
551 info->type = type;
552 route->nexthop[0].ifindex = ifindex;
553 if (nexthop_num && nexthop)
554 memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
555
556 /* create/update binding in external_id_table */
557 prefix_id.family = AF_INET;
558 prefix_id.prefixlen = 32;
559 prefix_id.u.prefix4.s_addr = htonl (info->id);
560 node = route_node_get (ospf6->external_id_table, &prefix_id);
561 node->info = route;
562
563 route = ospf6_route_add (route, ospf6->external_table);
564 route->route_option = info;
565
566 if (IS_OSPF6_DEBUG_ASBR)
567 {
568 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
569 zlog_info ("Advertise as AS-External Id:%s", ibuf);
570 }
571
hasso3b687352004-08-19 06:56:53 +0000572 route->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000573 ospf6_as_external_lsa_originate (route);
hasso508e53e2004-05-18 18:57:06 +0000574
575 /* Router-Bit (ASBR Flag) may have to be updated */
576 for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode))
577 {
578 oa = (struct ospf6_area *) getdata (lnode);
579 OSPF6_ROUTER_LSA_SCHEDULE (oa);
580 }
581}
582
583void
584ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
585{
586 struct ospf6_route *match;
587 struct ospf6_external_info *info = NULL;
588 struct route_node *node;
589 struct ospf6_lsa *lsa;
590 struct prefix prefix_id;
591 char pbuf[64], ibuf[16];
592 listnode lnode;
593 struct ospf6_area *oa;
594
595 match = ospf6_route_lookup (prefix, ospf6->external_table);
596 if (match == NULL)
597 {
598 if (IS_OSPF6_DEBUG_ASBR)
599 {
600 prefix2str (prefix, pbuf, sizeof (pbuf));
601 zlog_info ("No such route %s to withdraw", pbuf);
602 }
603 return;
604 }
605
606 info = match->route_option;
607 assert (info);
608
609 if (info->type != type)
610 {
611 if (IS_OSPF6_DEBUG_ASBR)
612 {
613 prefix2str (prefix, pbuf, sizeof (pbuf));
614 zlog_info ("Original protocol mismatch: %s", pbuf);
615 }
616 return;
617 }
618
619 if (IS_OSPF6_DEBUG_ASBR)
620 {
621 prefix2str (prefix, pbuf, sizeof (pbuf));
622 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
623 zlog_info ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
624 }
625
626 lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
627 htonl (info->id), ospf6->router_id, ospf6->lsdb);
628 if (lsa)
hasso6452df02004-08-15 05:52:07 +0000629 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000630
631 /* remove binding in external_id_table */
632 prefix_id.family = AF_INET;
633 prefix_id.prefixlen = 32;
634 prefix_id.u.prefix4.s_addr = htonl (info->id);
635 node = route_node_lookup (ospf6->external_id_table, &prefix_id);
636 assert (node);
637 node->info = NULL;
638 route_unlock_node (node);
639
640 ospf6_route_remove (match, ospf6->external_table);
641 XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
642
643 /* Router-Bit (ASBR Flag) may have to be updated */
644 for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode))
645 {
646 oa = (struct ospf6_area *) getdata (lnode);
647 OSPF6_ROUTER_LSA_SCHEDULE (oa);
paul718e3742002-12-13 20:15:29 +0000648 }
649}
650
651DEFUN (ospf6_redistribute,
652 ospf6_redistribute_cmd,
653 "redistribute (static|kernel|connected|ripng|bgp)",
654 "Redistribute\n"
655 "Static route\n"
656 "Kernel route\n"
657 "Connected route\n"
658 "RIPng route\n"
659 "BGP route\n"
660 )
661{
662 int type = 0;
663
664 if (strncmp (argv[0], "sta", 3) == 0)
665 type = ZEBRA_ROUTE_STATIC;
666 else if (strncmp (argv[0], "ker", 3) == 0)
667 type = ZEBRA_ROUTE_KERNEL;
668 else if (strncmp (argv[0], "con", 3) == 0)
669 type = ZEBRA_ROUTE_CONNECT;
670 else if (strncmp (argv[0], "rip", 3) == 0)
671 type = ZEBRA_ROUTE_RIPNG;
672 else if (strncmp (argv[0], "bgp", 3) == 0)
673 type = ZEBRA_ROUTE_BGP;
674
hasso508e53e2004-05-18 18:57:06 +0000675 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000676 ospf6_asbr_routemap_unset (type);
hasso508e53e2004-05-18 18:57:06 +0000677 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000678 return CMD_SUCCESS;
679}
680
681DEFUN (ospf6_redistribute_routemap,
682 ospf6_redistribute_routemap_cmd,
683 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
684 "Redistribute\n"
685 "Static routes\n"
686 "Kernel route\n"
687 "Connected route\n"
688 "RIPng route\n"
689 "BGP route\n"
690 "Route map reference\n"
691 "Route map name\n"
692 )
693{
694 int type = 0;
695
696 if (strncmp (argv[0], "sta", 3) == 0)
697 type = ZEBRA_ROUTE_STATIC;
698 else if (strncmp (argv[0], "ker", 3) == 0)
699 type = ZEBRA_ROUTE_KERNEL;
700 else if (strncmp (argv[0], "con", 3) == 0)
701 type = ZEBRA_ROUTE_CONNECT;
702 else if (strncmp (argv[0], "rip", 3) == 0)
703 type = ZEBRA_ROUTE_RIPNG;
704 else if (strncmp (argv[0], "bgp", 3) == 0)
705 type = ZEBRA_ROUTE_BGP;
706
hasso508e53e2004-05-18 18:57:06 +0000707 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000708 ospf6_asbr_routemap_set (type, argv[1]);
hasso508e53e2004-05-18 18:57:06 +0000709 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000710 return CMD_SUCCESS;
711}
712
713DEFUN (no_ospf6_redistribute,
714 no_ospf6_redistribute_cmd,
715 "no redistribute (static|kernel|connected|ripng|bgp)",
716 NO_STR
717 "Redistribute\n"
718 "Static route\n"
719 "Kernel route\n"
720 "Connected route\n"
721 "RIPng route\n"
722 "BGP route\n"
723 )
724{
725 int type = 0;
paul718e3742002-12-13 20:15:29 +0000726
727 if (strncmp (argv[0], "sta", 3) == 0)
728 type = ZEBRA_ROUTE_STATIC;
729 else if (strncmp (argv[0], "ker", 3) == 0)
730 type = ZEBRA_ROUTE_KERNEL;
731 else if (strncmp (argv[0], "con", 3) == 0)
732 type = ZEBRA_ROUTE_CONNECT;
733 else if (strncmp (argv[0], "rip", 3) == 0)
734 type = ZEBRA_ROUTE_RIPNG;
735 else if (strncmp (argv[0], "bgp", 3) == 0)
736 type = ZEBRA_ROUTE_BGP;
737
hasso508e53e2004-05-18 18:57:06 +0000738 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000739 ospf6_asbr_routemap_unset (type);
740
paul718e3742002-12-13 20:15:29 +0000741 return CMD_SUCCESS;
742}
743
paul718e3742002-12-13 20:15:29 +0000744int
745ospf6_redistribute_config_write (struct vty *vty)
746{
hasso508e53e2004-05-18 18:57:06 +0000747 int type;
paul718e3742002-12-13 20:15:29 +0000748
hasso508e53e2004-05-18 18:57:06 +0000749 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000750 {
hasso508e53e2004-05-18 18:57:06 +0000751 if (type == ZEBRA_ROUTE_OSPF6)
752 continue;
753 if (! ospf6_zebra_is_redistribute (type))
paul718e3742002-12-13 20:15:29 +0000754 continue;
755
hasso508e53e2004-05-18 18:57:06 +0000756 if (ospf6->rmap[type].name)
paul718e3742002-12-13 20:15:29 +0000757 vty_out (vty, " redistribute %s route-map %s%s",
hasso049207c2004-08-04 20:02:13 +0000758 ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
paul718e3742002-12-13 20:15:29 +0000759 else
760 vty_out (vty, " redistribute %s%s",
hasso049207c2004-08-04 20:02:13 +0000761 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000762 }
763
764 return 0;
765}
766
767void
768ospf6_redistribute_show_config (struct vty *vty)
769{
hasso508e53e2004-05-18 18:57:06 +0000770 int type;
771 int nroute[ZEBRA_ROUTE_MAX];
772 int total;
773 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000774 struct ospf6_external_info *info;
paul718e3742002-12-13 20:15:29 +0000775
hasso508e53e2004-05-18 18:57:06 +0000776 total = 0;
777 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
778 nroute[type] = 0;
779 for (route = ospf6_route_head (ospf6->external_table); route;
780 route = ospf6_route_next (route))
paul718e3742002-12-13 20:15:29 +0000781 {
hasso508e53e2004-05-18 18:57:06 +0000782 info = route->route_option;
783 nroute[info->type]++;
784 total++;
paul718e3742002-12-13 20:15:29 +0000785 }
786
hasso049207c2004-08-04 20:02:13 +0000787 vty_out (vty, "Redistributing External Routes from:%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000788 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000789 {
hasso508e53e2004-05-18 18:57:06 +0000790 if (type == ZEBRA_ROUTE_OSPF6)
791 continue;
792 if (! ospf6_zebra_is_redistribute (type))
hassoe26bbeb2003-05-25 21:39:29 +0000793 continue;
794
hasso508e53e2004-05-18 18:57:06 +0000795 if (ospf6->rmap[type].name)
796 vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
797 ZROUTE_NAME (type), ospf6->rmap[type].name,
798 (ospf6->rmap[type].map ? "" : " (not found !)"),
hasso049207c2004-08-04 20:02:13 +0000799 VNL);
paul718e3742002-12-13 20:15:29 +0000800 else
hasso508e53e2004-05-18 18:57:06 +0000801 vty_out (vty, " %d: %s%s", nroute[type],
hasso049207c2004-08-04 20:02:13 +0000802 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000803 }
hasso049207c2004-08-04 20:02:13 +0000804 vty_out (vty, "Total %d routes%s", total, VNL);
hasso508e53e2004-05-18 18:57:06 +0000805}
paul718e3742002-12-13 20:15:29 +0000806
paul718e3742002-12-13 20:15:29 +0000807
hasso508e53e2004-05-18 18:57:06 +0000808
809/* Routemap Functions */
810route_map_result_t
811ospf6_routemap_rule_match_address_prefixlist (void *rule,
812 struct prefix *prefix,
813 route_map_object_t type,
814 void *object)
815{
816 struct prefix_list *plist;
paul718e3742002-12-13 20:15:29 +0000817
hasso508e53e2004-05-18 18:57:06 +0000818 if (type != RMAP_OSPF6)
819 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000820
hasso508e53e2004-05-18 18:57:06 +0000821 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
822 if (plist == NULL)
823 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000824
hasso508e53e2004-05-18 18:57:06 +0000825 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
826 RMAP_NOMATCH : RMAP_MATCH);
827}
paul718e3742002-12-13 20:15:29 +0000828
hasso508e53e2004-05-18 18:57:06 +0000829void *
830ospf6_routemap_rule_match_address_prefixlist_compile (char *arg)
831{
832 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000833}
834
835void
hasso508e53e2004-05-18 18:57:06 +0000836ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000837{
hasso508e53e2004-05-18 18:57:06 +0000838 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
839}
paul718e3742002-12-13 20:15:29 +0000840
hasso508e53e2004-05-18 18:57:06 +0000841struct route_map_rule_cmd
842ospf6_routemap_rule_match_address_prefixlist_cmd =
843{
844 "ipv6 address prefix-list",
845 ospf6_routemap_rule_match_address_prefixlist,
846 ospf6_routemap_rule_match_address_prefixlist_compile,
847 ospf6_routemap_rule_match_address_prefixlist_free,
848};
hassoe26bbeb2003-05-25 21:39:29 +0000849
hasso508e53e2004-05-18 18:57:06 +0000850route_map_result_t
851ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
852 route_map_object_t type, void *object)
853{
854 char *metric_type = rule;
855 struct ospf6_route *route = object;
hassoe26bbeb2003-05-25 21:39:29 +0000856
hasso508e53e2004-05-18 18:57:06 +0000857 if (type != RMAP_OSPF6)
858 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000859
hasso508e53e2004-05-18 18:57:06 +0000860 if (strcmp (metric_type, "type-2") == 0)
861 route->path.metric_type = 2;
paul718e3742002-12-13 20:15:29 +0000862 else
hasso508e53e2004-05-18 18:57:06 +0000863 route->path.metric_type = 1;
paul718e3742002-12-13 20:15:29 +0000864
hasso508e53e2004-05-18 18:57:06 +0000865 return RMAP_OKAY;
866}
paul718e3742002-12-13 20:15:29 +0000867
hasso508e53e2004-05-18 18:57:06 +0000868void *
869ospf6_routemap_rule_set_metric_type_compile (char *arg)
870{
871 if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
872 return NULL;
873 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000874}
875
876void
hasso508e53e2004-05-18 18:57:06 +0000877ospf6_routemap_rule_set_metric_type_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000878{
hasso508e53e2004-05-18 18:57:06 +0000879 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
880}
paul718e3742002-12-13 20:15:29 +0000881
hasso508e53e2004-05-18 18:57:06 +0000882struct route_map_rule_cmd
883ospf6_routemap_rule_set_metric_type_cmd =
884{
885 "metric-type",
886 ospf6_routemap_rule_set_metric_type,
887 ospf6_routemap_rule_set_metric_type_compile,
888 ospf6_routemap_rule_set_metric_type_free,
889};
paul718e3742002-12-13 20:15:29 +0000890
hasso508e53e2004-05-18 18:57:06 +0000891route_map_result_t
892ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
893 route_map_object_t type, void *object)
894{
895 char *metric = rule;
896 struct ospf6_route *route = object;
paul718e3742002-12-13 20:15:29 +0000897
hasso508e53e2004-05-18 18:57:06 +0000898 if (type != RMAP_OSPF6)
899 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000900
hasso508e53e2004-05-18 18:57:06 +0000901 route->path.cost = atoi (metric);
902 return RMAP_OKAY;
903}
paul718e3742002-12-13 20:15:29 +0000904
hasso508e53e2004-05-18 18:57:06 +0000905void *
906ospf6_routemap_rule_set_metric_compile (char *arg)
907{
908 u_int32_t metric;
909 char *endp;
910 metric = strtoul (arg, &endp, 0);
911 if (metric > LS_INFINITY || *endp != '\0')
912 return NULL;
913 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000914}
915
916void
hasso508e53e2004-05-18 18:57:06 +0000917ospf6_routemap_rule_set_metric_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000918{
hasso508e53e2004-05-18 18:57:06 +0000919 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
920}
921
922struct route_map_rule_cmd
923ospf6_routemap_rule_set_metric_cmd =
924{
925 "metric",
926 ospf6_routemap_rule_set_metric,
927 ospf6_routemap_rule_set_metric_compile,
928 ospf6_routemap_rule_set_metric_free,
929};
930
931route_map_result_t
932ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
933 route_map_object_t type, void *object)
934{
935 char *forwarding = rule;
936 struct ospf6_route *route = object;
937 struct ospf6_external_info *info = route->route_option;
938
939 if (type != RMAP_OSPF6)
940 return RMAP_OKAY;
941
942 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
943 {
944 memset (&info->forwarding, 0, sizeof (struct in6_addr));
945 return RMAP_ERROR;
946 }
947
948 return RMAP_OKAY;
949}
950
951void *
952ospf6_routemap_rule_set_forwarding_compile (char *arg)
953{
954 struct in6_addr a;
955 if (inet_pton (AF_INET6, arg, &a) != 1)
956 return NULL;
957 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
958}
959
960void
961ospf6_routemap_rule_set_forwarding_free (void *rule)
962{
963 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
964}
965
966struct route_map_rule_cmd
967ospf6_routemap_rule_set_forwarding_cmd =
968{
969 "forwarding-address",
970 ospf6_routemap_rule_set_forwarding,
971 ospf6_routemap_rule_set_forwarding_compile,
972 ospf6_routemap_rule_set_forwarding_free,
973};
974
975int
976route_map_command_status (struct vty *vty, int ret)
977{
978 if (! ret)
979 return CMD_SUCCESS;
980
981 switch (ret)
982 {
983 case RMAP_RULE_MISSING:
hasso049207c2004-08-04 20:02:13 +0000984 vty_out (vty, "Can't find rule.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000985 break;
986 case RMAP_COMPILE_ERROR:
hasso049207c2004-08-04 20:02:13 +0000987 vty_out (vty, "Argument is malformed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000988 break;
989 default:
hasso049207c2004-08-04 20:02:13 +0000990 vty_out (vty, "route-map add set failed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000991 break;
992 }
993 return CMD_WARNING;
994}
995
996/* add "match address" */
997DEFUN (ospf6_routemap_match_address_prefixlist,
998 ospf6_routemap_match_address_prefixlist_cmd,
999 "match ipv6 address prefix-list WORD",
1000 "Match values\n"
1001 IPV6_STR
1002 "Match address of route\n"
1003 "Match entries of prefix-lists\n"
1004 "IPv6 prefix-list name\n")
1005{
1006 int ret = route_map_add_match ((struct route_map_index *) vty->index,
1007 "ipv6 address prefix-list", argv[0]);
1008 return route_map_command_status (vty, ret);
1009}
1010
1011/* delete "match address" */
1012DEFUN (ospf6_routemap_no_match_address_prefixlist,
1013 ospf6_routemap_no_match_address_prefixlist_cmd,
1014 "no match ipv6 address prefix-list WORD",
1015 NO_STR
1016 "Match values\n"
1017 IPV6_STR
1018 "Match address of route\n"
1019 "Match entries of prefix-lists\n"
1020 "IPv6 prefix-list name\n")
1021{
1022 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1023 "ipv6 address prefix-list", argv[0]);
1024 return route_map_command_status (vty, ret);
1025}
1026
1027/* add "set metric-type" */
1028DEFUN (ospf6_routemap_set_metric_type,
1029 ospf6_routemap_set_metric_type_cmd,
1030 "set metric-type (type-1|type-2)",
1031 "Set value\n"
1032 "Type of metric\n"
1033 "OSPF6 external type 1 metric\n"
1034 "OSPF6 external type 2 metric\n")
1035{
1036 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1037 "metric-type", argv[0]);
1038 return route_map_command_status (vty, ret);
1039}
1040
1041/* delete "set metric-type" */
1042DEFUN (ospf6_routemap_no_set_metric_type,
1043 ospf6_routemap_no_set_metric_type_cmd,
1044 "no set metric-type (type-1|type-2)",
1045 NO_STR
1046 "Set value\n"
1047 "Type of metric\n"
1048 "OSPF6 external type 1 metric\n"
1049 "OSPF6 external type 2 metric\n")
1050{
1051 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1052 "metric-type", argv[0]);
1053 return route_map_command_status (vty, ret);
1054}
1055
1056/* add "set metric" */
1057DEFUN (set_metric,
1058 set_metric_cmd,
1059 "set metric <0-4294967295>",
1060 "Set value\n"
1061 "Metric value\n"
1062 "Metric value\n")
1063{
1064 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1065 "metric", argv[0]);
1066 return route_map_command_status (vty, ret);
1067}
1068
1069/* delete "set metric" */
1070DEFUN (no_set_metric,
1071 no_set_metric_cmd,
1072 "no set metric <0-4294967295>",
1073 NO_STR
1074 "Set value\n"
1075 "Metric\n"
1076 "METRIC value\n")
1077{
1078 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1079 "metric", argv[0]);
1080 return route_map_command_status (vty, ret);
1081}
1082
1083/* add "set forwarding-address" */
1084DEFUN (ospf6_routemap_set_forwarding,
1085 ospf6_routemap_set_forwarding_cmd,
1086 "set forwarding-address X:X::X:X",
1087 "Set value\n"
1088 "Forwarding Address\n"
1089 "IPv6 Address\n")
1090{
1091 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1092 "forwarding-address", argv[0]);
1093 return route_map_command_status (vty, ret);
1094}
1095
1096/* delete "set forwarding-address" */
1097DEFUN (ospf6_routemap_no_set_forwarding,
1098 ospf6_routemap_no_set_forwarding_cmd,
1099 "no set forwarding-address X:X::X:X",
1100 NO_STR
1101 "Set value\n"
1102 "Forwarding Address\n"
1103 "IPv6 Address\n")
1104{
1105 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1106 "forwarding-address", argv[0]);
1107 return route_map_command_status (vty, ret);
1108}
1109
1110void
1111ospf6_routemap_init ()
1112{
1113 route_map_init ();
1114 route_map_init_vty ();
1115 route_map_add_hook (ospf6_asbr_routemap_update);
1116 route_map_delete_hook (ospf6_asbr_routemap_update);
1117
1118 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
1119 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
1120 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
1121 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
1122
1123 /* Match address prefix-list */
1124 install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
1125 install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
1126
1127 /* ASE Metric Type (e.g. Type-1/Type-2) */
1128 install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
1129 install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
1130
1131 /* ASE Metric */
1132 install_element (RMAP_NODE, &set_metric_cmd);
1133 install_element (RMAP_NODE, &no_set_metric_cmd);
1134
1135 /* ASE Metric */
1136 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
1137 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
1138}
1139
1140
1141/* Display functions */
1142int
1143ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
1144{
1145 struct ospf6_as_external_lsa *external;
paul718e3742002-12-13 20:15:29 +00001146 char buf[64];
hasso508e53e2004-05-18 18:57:06 +00001147 struct in6_addr in6, *forwarding;
paul718e3742002-12-13 20:15:29 +00001148
1149 assert (lsa->header);
hasso508e53e2004-05-18 18:57:06 +00001150 external = (struct ospf6_as_external_lsa *)
1151 OSPF6_LSA_HEADER_END (lsa->header);
paul718e3742002-12-13 20:15:29 +00001152
1153 /* bits */
hasso508e53e2004-05-18 18:57:06 +00001154 snprintf (buf, sizeof (buf), "%c%c%c",
1155 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
1156 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
1157 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
paul718e3742002-12-13 20:15:29 +00001158
hasso049207c2004-08-04 20:02:13 +00001159 vty_out (vty, " Bits: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +00001160 vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
hasso049207c2004-08-04 20:02:13 +00001161 VNL);
paul718e3742002-12-13 20:15:29 +00001162
hasso508e53e2004-05-18 18:57:06 +00001163 ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1164 buf, sizeof (buf));
1165 vty_out (vty, " Prefix Options: %s%s", buf,
hasso049207c2004-08-04 20:02:13 +00001166 VNL);
paul718e3742002-12-13 20:15:29 +00001167
1168 vty_out (vty, " Referenced LSType: %d%s",
hasso508e53e2004-05-18 18:57:06 +00001169 ntohs (external->prefix.prefix_refer_lstype),
hasso049207c2004-08-04 20:02:13 +00001170 VNL);
paul718e3742002-12-13 20:15:29 +00001171
hasso508e53e2004-05-18 18:57:06 +00001172 ospf6_prefix_in6_addr (&in6, &external->prefix);
paul718e3742002-12-13 20:15:29 +00001173 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
hasso508e53e2004-05-18 18:57:06 +00001174 vty_out (vty, " Prefix: %s/%d%s", buf,
hasso049207c2004-08-04 20:02:13 +00001175 external->prefix.prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +00001176
1177 /* Forwarding-Address */
1178 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
1179 {
hasso508e53e2004-05-18 18:57:06 +00001180 forwarding = (struct in6_addr *)
1181 ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
1182 OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
1183 inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +00001184 vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
paul718e3742002-12-13 20:15:29 +00001185 }
1186
1187 return 0;
1188}
1189
1190void
hasso508e53e2004-05-18 18:57:06 +00001191ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +00001192{
hasso508e53e2004-05-18 18:57:06 +00001193 struct ospf6_external_info *info = route->route_option;
1194 char prefix[64], id[16], forwarding[64];
1195 u_int32_t tmp_id;
1196
1197 prefix2str (&route->prefix, prefix, sizeof (prefix));
1198 tmp_id = ntohl (info->id);
1199 inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
1200 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
1201 inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
1202 else
1203 snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
1204 route->nexthop[0].ifindex);
1205
1206 vty_out (vty, "%s %-32s %-15s type-%d %5lu %s%s",
1207 ZROUTE_ABNAME (info->type),
1208 prefix, id, route->path.metric_type,
1209 (u_long) (route->path.metric_type == 2 ?
1210 route->path.cost_e2 : route->path.cost),
hasso049207c2004-08-04 20:02:13 +00001211 forwarding, VNL);
paul718e3742002-12-13 20:15:29 +00001212}
1213
hasso508e53e2004-05-18 18:57:06 +00001214DEFUN (show_ipv6_ospf6_redistribute,
1215 show_ipv6_ospf6_redistribute_cmd,
1216 "show ipv6 ospf6 redistribute",
paul718e3742002-12-13 20:15:29 +00001217 SHOW_STR
1218 IP6_STR
paul718e3742002-12-13 20:15:29 +00001219 OSPF6_STR
1220 "redistributing External information\n"
1221 )
1222{
hasso508e53e2004-05-18 18:57:06 +00001223 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +00001224
hasso508e53e2004-05-18 18:57:06 +00001225 ospf6_redistribute_show_config (vty);
1226
1227 for (route = ospf6_route_head (ospf6->external_table); route;
1228 route = ospf6_route_next (route))
1229 ospf6_asbr_external_route_show (vty, route);
1230
paul718e3742002-12-13 20:15:29 +00001231 return CMD_SUCCESS;
1232}
1233
hasso6452df02004-08-15 05:52:07 +00001234struct ospf6_lsa_handler as_external_handler =
hasso508e53e2004-05-18 18:57:06 +00001235{
hasso6452df02004-08-15 05:52:07 +00001236 OSPF6_LSTYPE_AS_EXTERNAL,
1237 "AS-External",
1238 ospf6_as_external_lsa_show
1239};
hasso508e53e2004-05-18 18:57:06 +00001240
paul718e3742002-12-13 20:15:29 +00001241void
1242ospf6_asbr_init ()
1243{
hasso508e53e2004-05-18 18:57:06 +00001244 ospf6_routemap_init ();
paul718e3742002-12-13 20:15:29 +00001245
hasso6452df02004-08-15 05:52:07 +00001246 ospf6_install_lsa_handler (&as_external_handler);
paul718e3742002-12-13 20:15:29 +00001247
hasso508e53e2004-05-18 18:57:06 +00001248 install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
1249 install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
1250
paul718e3742002-12-13 20:15:29 +00001251 install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
1252 install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
1253 install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
1254}
1255
1256
hasso508e53e2004-05-18 18:57:06 +00001257DEFUN (debug_ospf6_asbr,
1258 debug_ospf6_asbr_cmd,
1259 "debug ospf6 asbr",
1260 DEBUG_STR
1261 OSPF6_STR
1262 "Debug OSPFv3 ASBR function\n"
1263 )
1264{
1265 OSPF6_DEBUG_ASBR_ON ();
1266 return CMD_SUCCESS;
1267}
1268
1269DEFUN (no_debug_ospf6_asbr,
1270 no_debug_ospf6_asbr_cmd,
1271 "no debug ospf6 asbr",
1272 NO_STR
1273 DEBUG_STR
1274 OSPF6_STR
1275 "Debug OSPFv3 ASBR function\n"
1276 )
1277{
1278 OSPF6_DEBUG_ASBR_OFF ();
1279 return CMD_SUCCESS;
1280}
1281
1282int
1283config_write_ospf6_debug_asbr (struct vty *vty)
1284{
1285 if (IS_OSPF6_DEBUG_ASBR)
hasso049207c2004-08-04 20:02:13 +00001286 vty_out (vty, "debug ospf6 asbr%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001287 return 0;
1288}
1289
1290void
1291install_element_ospf6_debug_asbr ()
1292{
1293 install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
1294 install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
1295 install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
1296 install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
1297}
1298
1299