blob: 286b5c1bfe1b6f0a41187f57336e57c3215b7b03 [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
ajsf52d13c2005-10-01 17:38:06 +000053#define ZROUTE_NAME(x) zebra_route_string(x)
hasso508e53e2004-05-18 18:57:06 +000054
55/* AS External LSA origination */
56void
hasso6452df02004-08-15 05:52:07 +000057ospf6_as_external_lsa_originate (struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +000058{
hasso508e53e2004-05-18 18:57:06 +000059 char buffer[OSPF6_MAX_LSASIZE];
60 struct ospf6_lsa_header *lsa_header;
61 struct ospf6_lsa *old, *lsa;
paul718e3742002-12-13 20:15:29 +000062
hasso508e53e2004-05-18 18:57:06 +000063 struct ospf6_as_external_lsa *as_external_lsa;
64 char buf[64];
65 caddr_t p;
paul718e3742002-12-13 20:15:29 +000066
hasso508e53e2004-05-18 18:57:06 +000067 /* find previous LSA */
68 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
hasso6452df02004-08-15 05:52:07 +000069 route->path.origin.id, ospf6->router_id,
hasso508e53e2004-05-18 18:57:06 +000070 ospf6->lsdb);
71
hasso1e058382004-09-01 21:36:14 +000072 if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +000073 {
74 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +000075 zlog_debug ("Originate AS-External-LSA for %s", buf);
hasso508e53e2004-05-18 18:57:06 +000076 }
77
78 /* prepare buffer */
79 memset (buffer, 0, sizeof (buffer));
80 lsa_header = (struct ospf6_lsa_header *) buffer;
81 as_external_lsa = (struct ospf6_as_external_lsa *)
82 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
83 p = (caddr_t)
84 ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));
85
86 /* Fill AS-External-LSA */
87 /* Metric type */
88 if (route->path.metric_type == 2)
89 SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
90 else
91 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
92
93 /* forwarding address */
hasso6452df02004-08-15 05:52:07 +000094 if (! IN6_IS_ADDR_UNSPECIFIED (&route->nexthop[0].address))
hasso508e53e2004-05-18 18:57:06 +000095 SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
96 else
97 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
98
99 /* external route tag */
100 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
101
102 /* Set metric */
103 OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
104
105 /* prefixlen */
106 as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
107
108 /* PrefixOptions */
109 as_external_lsa->prefix.prefix_options = route->path.prefix_options;
110
111 /* don't use refer LS-type */
112 as_external_lsa->prefix.prefix_refer_lstype = htons (0);
113
114 /* set Prefix */
115 memcpy (p, &route->prefix.u.prefix6,
116 OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
117 ospf6_prefix_apply_mask (&as_external_lsa->prefix);
118 p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
119
120 /* Forwarding address */
121 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
122 {
hasso6452df02004-08-15 05:52:07 +0000123 memcpy (p, &route->nexthop[0].address, sizeof (struct in6_addr));
hasso508e53e2004-05-18 18:57:06 +0000124 p += sizeof (struct in6_addr);
125 }
126
127 /* External Route Tag */
128 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
129 {
130 /* xxx */
131 }
132
133 /* Fill LSA Header */
134 lsa_header->age = 0;
135 lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
hasso6452df02004-08-15 05:52:07 +0000136 lsa_header->id = route->path.origin.id;
hasso508e53e2004-05-18 18:57:06 +0000137 lsa_header->adv_router = ospf6->router_id;
138 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000139 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
140 lsa_header->adv_router, ospf6->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000141 lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
142
143 /* LSA checksum */
144 ospf6_lsa_checksum (lsa_header);
145
146 /* create LSA */
147 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000148
149 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000150 ospf6_lsa_originate_process (lsa, ospf6);
hasso508e53e2004-05-18 18:57:06 +0000151}
152
hasso508e53e2004-05-18 18:57:06 +0000153
154void
155ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
156{
157 struct ospf6_as_external_lsa *external;
158 struct prefix asbr_id;
159 struct ospf6_route *asbr_entry, *route;
160 char buf[64];
161 int i;
162
163 external = (struct ospf6_as_external_lsa *)
164 OSPF6_LSA_HEADER_END (lsa->header);
165
hasso1e058382004-09-01 21:36:14 +0000166 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000167 zlog_debug ("Calculate AS-External route for %s", lsa->name);
hasso508e53e2004-05-18 18:57:06 +0000168
169 if (lsa->header->adv_router == ospf6->router_id)
170 {
hasso1e058382004-09-01 21:36:14 +0000171 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000172 zlog_debug ("Ignore self-originated AS-External-LSA");
hasso508e53e2004-05-18 18:57:06 +0000173 return;
174 }
175
176 if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
177 {
hasso1e058382004-09-01 21:36:14 +0000178 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000179 zlog_debug ("Ignore LSA with LSInfinity Metric");
hasso508e53e2004-05-18 18:57:06 +0000180 return;
181 }
182
hassoccb59b12004-08-25 09:10:37 +0000183 ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);
hasso6452df02004-08-15 05:52:07 +0000184 asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
hasso63069ad2004-09-02 13:01:01 +0000185 if (asbr_entry == NULL ||
186 ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))
hasso508e53e2004-05-18 18:57:06 +0000187 {
hasso1e058382004-09-01 21:36:14 +0000188 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000189 {
190 prefix2str (&asbr_id, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000191 zlog_debug ("ASBR entry not found: %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000192 }
193 return;
194 }
195
196 route = ospf6_route_create ();
197 route->type = OSPF6_DEST_TYPE_NETWORK;
198 route->prefix.family = AF_INET6;
199 route->prefix.prefixlen = external->prefix.prefix_length;
200 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
201
202 route->path.area_id = asbr_entry->path.area_id;
203 route->path.origin.type = lsa->header->type;
204 route->path.origin.id = lsa->header->id;
205 route->path.origin.adv_router = lsa->header->adv_router;
206
207 route->path.prefix_options = external->prefix.prefix_options;
208 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
209 {
210 route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
211 route->path.metric_type = 2;
212 route->path.cost = asbr_entry->path.cost;
213 route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
214 }
215 else
216 {
217 route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
218 route->path.metric_type = 1;
219 route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
220 route->path.cost_e2 = 0;
221 }
222
223 for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
224 ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
225
hasso1e058382004-09-01 21:36:14 +0000226 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000227 {
228 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000229 zlog_debug ("AS-External route add: %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000230 }
231
232 ospf6_route_add (route, ospf6->route_table);
233}
234
235void
236ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
237{
238 struct ospf6_as_external_lsa *external;
239 struct prefix prefix;
240 struct ospf6_route *route;
241 char buf[64];
242
243 external = (struct ospf6_as_external_lsa *)
244 OSPF6_LSA_HEADER_END (lsa->header);
245
hasso1e058382004-09-01 21:36:14 +0000246 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000247 zlog_debug ("Withdraw AS-External route for %s", lsa->name);
hasso508e53e2004-05-18 18:57:06 +0000248
249 if (lsa->header->adv_router == ospf6->router_id)
250 {
hasso1e058382004-09-01 21:36:14 +0000251 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000252 zlog_debug ("Ignore self-originated AS-External-LSA");
hasso508e53e2004-05-18 18:57:06 +0000253 return;
254 }
255
256 memset (&prefix, 0, sizeof (struct prefix));
257 prefix.family = AF_INET6;
258 prefix.prefixlen = external->prefix.prefix_length;
259 ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
260
261 route = ospf6_route_lookup (&prefix, ospf6->route_table);
262 if (route == NULL)
263 {
hasso1e058382004-09-01 21:36:14 +0000264 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000265 {
266 prefix2str (&prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000267 zlog_debug ("AS-External route %s not found", buf);
hasso508e53e2004-05-18 18:57:06 +0000268 }
269 return;
270 }
271
272 for (ospf6_route_lock (route);
273 route && ospf6_route_is_prefix (&prefix, route);
274 route = ospf6_route_next (route))
275 {
276 if (route->type != OSPF6_DEST_TYPE_NETWORK)
277 continue;
278 if (route->path.origin.type != lsa->header->type)
279 continue;
280 if (route->path.origin.id != lsa->header->id)
281 continue;
282 if (route->path.origin.adv_router != lsa->header->adv_router)
283 continue;
284
hasso1e058382004-09-01 21:36:14 +0000285 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000286 {
287 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000288 zlog_debug ("AS-External route remove: %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000289 }
290 ospf6_route_remove (route, ospf6->route_table);
291 }
292}
293
294void
295ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
296{
297 char buf[64];
298 struct ospf6_lsa *lsa;
299 u_int16_t type;
300 u_int32_t router;
301
hasso1e058382004-09-01 21:36:14 +0000302 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000303 {
304 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000305 zlog_debug ("New ASBR %s found", buf);
hasso508e53e2004-05-18 18:57:06 +0000306 }
307
308 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
309 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
310 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
311 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
312 {
313 if (! OSPF6_LSA_IS_MAXAGE (lsa))
314 ospf6_asbr_lsa_add (lsa);
315 }
316
hasso1e058382004-09-01 21:36:14 +0000317 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000318 {
319 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000320 zlog_debug ("Calculation for new ASBR %s done", buf);
hasso508e53e2004-05-18 18:57:06 +0000321 }
322}
323
324void
325ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
326{
327 char buf[64];
328 struct ospf6_lsa *lsa;
329 u_int16_t type;
330 u_int32_t router;
331
hasso1e058382004-09-01 21:36:14 +0000332 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000333 {
334 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000335 zlog_debug ("ASBR %s disappeared", buf);
hasso508e53e2004-05-18 18:57:06 +0000336 }
337
338 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
339 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
340 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
341 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
342 ospf6_asbr_lsa_remove (lsa);
343
hasso1e058382004-09-01 21:36:14 +0000344 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000345 {
346 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000347 zlog_debug ("Calculation for old ASBR %s done", buf);
hasso508e53e2004-05-18 18:57:06 +0000348 }
349}
350
351
352
paul718e3742002-12-13 20:15:29 +0000353/* redistribute function */
hasso508e53e2004-05-18 18:57:06 +0000354
paul718e3742002-12-13 20:15:29 +0000355void
paul0c083ee2004-10-10 12:54:58 +0000356ospf6_asbr_routemap_set (int type, const char *mapname)
paul718e3742002-12-13 20:15:29 +0000357{
hasso508e53e2004-05-18 18:57:06 +0000358 if (ospf6->rmap[type].name)
359 free (ospf6->rmap[type].name);
360 ospf6->rmap[type].name = strdup (mapname);
361 ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
paul718e3742002-12-13 20:15:29 +0000362}
363
364void
365ospf6_asbr_routemap_unset (int type)
366{
hasso508e53e2004-05-18 18:57:06 +0000367 if (ospf6->rmap[type].name)
368 free (ospf6->rmap[type].name);
369 ospf6->rmap[type].name = NULL;
370 ospf6->rmap[type].map = NULL;
paul718e3742002-12-13 20:15:29 +0000371}
372
373void
paul0c083ee2004-10-10 12:54:58 +0000374ospf6_asbr_routemap_update (const char *mapname)
paul718e3742002-12-13 20:15:29 +0000375{
hasso508e53e2004-05-18 18:57:06 +0000376 int type;
377
378 if (ospf6 == NULL)
379 return;
380
381 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000382 {
hasso508e53e2004-05-18 18:57:06 +0000383 if (ospf6->rmap[type].name)
384 ospf6->rmap[type].map =
385 route_map_lookup_by_name (ospf6->rmap[type].name);
paul718e3742002-12-13 20:15:29 +0000386 else
hasso508e53e2004-05-18 18:57:06 +0000387 ospf6->rmap[type].map = NULL;
388 }
389}
390
391int
392ospf6_asbr_is_asbr (struct ospf6 *o)
393{
394 return o->external_table->count;
395}
396
397void
398ospf6_asbr_redistribute_set (int type)
399{
400 ospf6_zebra_redistribute (type);
401}
402
403void
404ospf6_asbr_redistribute_unset (int type)
405{
406 struct ospf6_route *route;
407 struct ospf6_external_info *info;
408
409 ospf6_zebra_no_redistribute (type);
410
411 for (route = ospf6_route_head (ospf6->external_table); route;
412 route = ospf6_route_next (route))
413 {
414 info = route->route_option;
415 if (info->type != type)
416 continue;
417
418 ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
419 &route->prefix);
420 }
421}
422
423void
424ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
425 u_int nexthop_num, struct in6_addr *nexthop)
426{
427 int ret;
428 struct ospf6_route troute;
429 struct ospf6_external_info tinfo;
430 struct ospf6_route *route, *match;
431 struct ospf6_external_info *info;
432 struct prefix prefix_id;
433 struct route_node *node;
434 char pbuf[64], ibuf[16];
paul1eb8ef22005-04-07 07:30:20 +0000435 struct listnode *lnode, *lnnode;
hasso508e53e2004-05-18 18:57:06 +0000436 struct ospf6_area *oa;
437
438 if (! ospf6_zebra_is_redistribute (type))
439 return;
440
441 if (IS_OSPF6_DEBUG_ASBR)
442 {
443 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000444 zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
hasso508e53e2004-05-18 18:57:06 +0000445 }
446
447 /* if route-map was specified but not found, do not advertise */
448 if (ospf6->rmap[type].name)
449 {
450 if (ospf6->rmap[type].map == NULL)
hasso03d52f82004-09-29 00:26:19 +0000451 ospf6_asbr_routemap_update (NULL);
hasso508e53e2004-05-18 18:57:06 +0000452 if (ospf6->rmap[type].map == NULL)
453 {
454 zlog_warn ("route-map \"%s\" not found, suppress redistributing",
455 ospf6->rmap[type].name);
456 return;
457 }
458 }
459
460 /* apply route-map */
461 if (ospf6->rmap[type].map)
462 {
463 memset (&troute, 0, sizeof (troute));
464 memset (&tinfo, 0, sizeof (tinfo));
465 troute.route_option = &tinfo;
466
467 ret = route_map_apply (ospf6->rmap[type].map, prefix,
468 RMAP_OSPF6, &troute);
paul47828742005-08-10 15:46:11 +0000469 if (ret == RMAP_DENYMATCH)
hasso508e53e2004-05-18 18:57:06 +0000470 {
471 if (IS_OSPF6_DEBUG_ASBR)
hassoc6487d62004-12-24 06:00:11 +0000472 zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
hasso508e53e2004-05-18 18:57:06 +0000473 return;
474 }
475 }
476
477 match = ospf6_route_lookup (prefix, ospf6->external_table);
478 if (match)
479 {
480 info = match->route_option;
481
482 /* copy result of route-map */
483 if (ospf6->rmap[type].map)
484 {
485 if (troute.path.metric_type)
486 match->path.metric_type = troute.path.metric_type;
487 if (troute.path.cost)
488 match->path.cost = troute.path.cost;
489 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
490 memcpy (&info->forwarding, &tinfo.forwarding,
491 sizeof (struct in6_addr));
492 }
493
494 info->type = type;
495 match->nexthop[0].ifindex = ifindex;
496 if (nexthop_num && nexthop)
497 memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
498
499 /* create/update binding in external_id_table */
500 prefix_id.family = AF_INET;
501 prefix_id.prefixlen = 32;
502 prefix_id.u.prefix4.s_addr = htonl (info->id);
503 node = route_node_get (ospf6->external_id_table, &prefix_id);
504 node->info = match;
505
506 if (IS_OSPF6_DEBUG_ASBR)
507 {
508 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000509 zlog_debug ("Advertise as AS-External Id:%s", ibuf);
hasso508e53e2004-05-18 18:57:06 +0000510 }
511
hasso3b687352004-08-19 06:56:53 +0000512 match->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000513 ospf6_as_external_lsa_originate (match);
hasso508e53e2004-05-18 18:57:06 +0000514 return;
515 }
516
517 /* create new entry */
518 route = ospf6_route_create ();
519 route->type = OSPF6_DEST_TYPE_NETWORK;
520 memcpy (&route->prefix, prefix, sizeof (struct prefix));
521
522 info = (struct ospf6_external_info *)
523 XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
524 memset (info, 0, sizeof (struct ospf6_external_info));
525 route->route_option = info;
526 info->id = ospf6->external_id++;
527
528 /* copy result of route-map */
529 if (ospf6->rmap[type].map)
530 {
531 if (troute.path.metric_type)
532 route->path.metric_type = troute.path.metric_type;
533 if (troute.path.cost)
534 route->path.cost = troute.path.cost;
535 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
536 memcpy (&info->forwarding, &tinfo.forwarding,
537 sizeof (struct in6_addr));
538 }
539
540 info->type = type;
541 route->nexthop[0].ifindex = ifindex;
542 if (nexthop_num && nexthop)
543 memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
544
545 /* create/update binding in external_id_table */
546 prefix_id.family = AF_INET;
547 prefix_id.prefixlen = 32;
548 prefix_id.u.prefix4.s_addr = htonl (info->id);
549 node = route_node_get (ospf6->external_id_table, &prefix_id);
550 node->info = route;
551
552 route = ospf6_route_add (route, ospf6->external_table);
553 route->route_option = info;
554
555 if (IS_OSPF6_DEBUG_ASBR)
556 {
557 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000558 zlog_debug ("Advertise as AS-External Id:%s", ibuf);
hasso508e53e2004-05-18 18:57:06 +0000559 }
560
hasso3b687352004-08-19 06:56:53 +0000561 route->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000562 ospf6_as_external_lsa_originate (route);
hasso508e53e2004-05-18 18:57:06 +0000563
564 /* Router-Bit (ASBR Flag) may have to be updated */
paul1eb8ef22005-04-07 07:30:20 +0000565 for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
566 OSPF6_ROUTER_LSA_SCHEDULE (oa);
hasso508e53e2004-05-18 18:57:06 +0000567}
568
569void
570ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
571{
572 struct ospf6_route *match;
573 struct ospf6_external_info *info = NULL;
574 struct route_node *node;
575 struct ospf6_lsa *lsa;
576 struct prefix prefix_id;
577 char pbuf[64], ibuf[16];
paul1eb8ef22005-04-07 07:30:20 +0000578 struct listnode *lnode, *lnnode;
hasso508e53e2004-05-18 18:57:06 +0000579 struct ospf6_area *oa;
580
581 match = ospf6_route_lookup (prefix, ospf6->external_table);
582 if (match == NULL)
583 {
584 if (IS_OSPF6_DEBUG_ASBR)
585 {
586 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000587 zlog_debug ("No such route %s to withdraw", pbuf);
hasso508e53e2004-05-18 18:57:06 +0000588 }
589 return;
590 }
591
592 info = match->route_option;
593 assert (info);
594
595 if (info->type != type)
596 {
597 if (IS_OSPF6_DEBUG_ASBR)
598 {
599 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000600 zlog_debug ("Original protocol mismatch: %s", pbuf);
hasso508e53e2004-05-18 18:57:06 +0000601 }
602 return;
603 }
604
605 if (IS_OSPF6_DEBUG_ASBR)
606 {
607 prefix2str (prefix, pbuf, sizeof (pbuf));
608 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000609 zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
hasso508e53e2004-05-18 18:57:06 +0000610 }
611
612 lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
613 htonl (info->id), ospf6->router_id, ospf6->lsdb);
614 if (lsa)
hasso6452df02004-08-15 05:52:07 +0000615 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000616
617 /* remove binding in external_id_table */
618 prefix_id.family = AF_INET;
619 prefix_id.prefixlen = 32;
620 prefix_id.u.prefix4.s_addr = htonl (info->id);
621 node = route_node_lookup (ospf6->external_id_table, &prefix_id);
622 assert (node);
623 node->info = NULL;
624 route_unlock_node (node);
625
626 ospf6_route_remove (match, ospf6->external_table);
627 XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
628
629 /* Router-Bit (ASBR Flag) may have to be updated */
paul1eb8ef22005-04-07 07:30:20 +0000630 for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
631 OSPF6_ROUTER_LSA_SCHEDULE (oa);
paul718e3742002-12-13 20:15:29 +0000632}
633
634DEFUN (ospf6_redistribute,
635 ospf6_redistribute_cmd,
636 "redistribute (static|kernel|connected|ripng|bgp)",
637 "Redistribute\n"
638 "Static route\n"
639 "Kernel route\n"
640 "Connected route\n"
641 "RIPng route\n"
642 "BGP route\n"
643 )
644{
645 int type = 0;
646
647 if (strncmp (argv[0], "sta", 3) == 0)
648 type = ZEBRA_ROUTE_STATIC;
649 else if (strncmp (argv[0], "ker", 3) == 0)
650 type = ZEBRA_ROUTE_KERNEL;
651 else if (strncmp (argv[0], "con", 3) == 0)
652 type = ZEBRA_ROUTE_CONNECT;
653 else if (strncmp (argv[0], "rip", 3) == 0)
654 type = ZEBRA_ROUTE_RIPNG;
655 else if (strncmp (argv[0], "bgp", 3) == 0)
656 type = ZEBRA_ROUTE_BGP;
657
hasso508e53e2004-05-18 18:57:06 +0000658 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000659 ospf6_asbr_routemap_unset (type);
hasso508e53e2004-05-18 18:57:06 +0000660 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000661 return CMD_SUCCESS;
662}
663
664DEFUN (ospf6_redistribute_routemap,
665 ospf6_redistribute_routemap_cmd,
666 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
667 "Redistribute\n"
668 "Static routes\n"
669 "Kernel route\n"
670 "Connected route\n"
671 "RIPng route\n"
672 "BGP route\n"
673 "Route map reference\n"
674 "Route map name\n"
675 )
676{
677 int type = 0;
678
679 if (strncmp (argv[0], "sta", 3) == 0)
680 type = ZEBRA_ROUTE_STATIC;
681 else if (strncmp (argv[0], "ker", 3) == 0)
682 type = ZEBRA_ROUTE_KERNEL;
683 else if (strncmp (argv[0], "con", 3) == 0)
684 type = ZEBRA_ROUTE_CONNECT;
685 else if (strncmp (argv[0], "rip", 3) == 0)
686 type = ZEBRA_ROUTE_RIPNG;
687 else if (strncmp (argv[0], "bgp", 3) == 0)
688 type = ZEBRA_ROUTE_BGP;
689
hasso508e53e2004-05-18 18:57:06 +0000690 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000691 ospf6_asbr_routemap_set (type, argv[1]);
hasso508e53e2004-05-18 18:57:06 +0000692 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000693 return CMD_SUCCESS;
694}
695
696DEFUN (no_ospf6_redistribute,
697 no_ospf6_redistribute_cmd,
698 "no redistribute (static|kernel|connected|ripng|bgp)",
699 NO_STR
700 "Redistribute\n"
701 "Static route\n"
702 "Kernel route\n"
703 "Connected route\n"
704 "RIPng route\n"
705 "BGP route\n"
706 )
707{
708 int type = 0;
paul718e3742002-12-13 20:15:29 +0000709
710 if (strncmp (argv[0], "sta", 3) == 0)
711 type = ZEBRA_ROUTE_STATIC;
712 else if (strncmp (argv[0], "ker", 3) == 0)
713 type = ZEBRA_ROUTE_KERNEL;
714 else if (strncmp (argv[0], "con", 3) == 0)
715 type = ZEBRA_ROUTE_CONNECT;
716 else if (strncmp (argv[0], "rip", 3) == 0)
717 type = ZEBRA_ROUTE_RIPNG;
718 else if (strncmp (argv[0], "bgp", 3) == 0)
719 type = ZEBRA_ROUTE_BGP;
720
hasso508e53e2004-05-18 18:57:06 +0000721 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000722 ospf6_asbr_routemap_unset (type);
723
paul718e3742002-12-13 20:15:29 +0000724 return CMD_SUCCESS;
725}
726
paul718e3742002-12-13 20:15:29 +0000727int
728ospf6_redistribute_config_write (struct vty *vty)
729{
hasso508e53e2004-05-18 18:57:06 +0000730 int type;
paul718e3742002-12-13 20:15:29 +0000731
hasso508e53e2004-05-18 18:57:06 +0000732 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000733 {
hasso508e53e2004-05-18 18:57:06 +0000734 if (type == ZEBRA_ROUTE_OSPF6)
735 continue;
736 if (! ospf6_zebra_is_redistribute (type))
paul718e3742002-12-13 20:15:29 +0000737 continue;
738
hasso508e53e2004-05-18 18:57:06 +0000739 if (ospf6->rmap[type].name)
paul718e3742002-12-13 20:15:29 +0000740 vty_out (vty, " redistribute %s route-map %s%s",
hasso049207c2004-08-04 20:02:13 +0000741 ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
paul718e3742002-12-13 20:15:29 +0000742 else
743 vty_out (vty, " redistribute %s%s",
hasso049207c2004-08-04 20:02:13 +0000744 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000745 }
746
747 return 0;
748}
749
750void
751ospf6_redistribute_show_config (struct vty *vty)
752{
hasso508e53e2004-05-18 18:57:06 +0000753 int type;
754 int nroute[ZEBRA_ROUTE_MAX];
755 int total;
756 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000757 struct ospf6_external_info *info;
paul718e3742002-12-13 20:15:29 +0000758
hasso508e53e2004-05-18 18:57:06 +0000759 total = 0;
760 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
761 nroute[type] = 0;
762 for (route = ospf6_route_head (ospf6->external_table); route;
763 route = ospf6_route_next (route))
paul718e3742002-12-13 20:15:29 +0000764 {
hasso508e53e2004-05-18 18:57:06 +0000765 info = route->route_option;
766 nroute[info->type]++;
767 total++;
paul718e3742002-12-13 20:15:29 +0000768 }
769
hasso049207c2004-08-04 20:02:13 +0000770 vty_out (vty, "Redistributing External Routes from:%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000771 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000772 {
hasso508e53e2004-05-18 18:57:06 +0000773 if (type == ZEBRA_ROUTE_OSPF6)
774 continue;
775 if (! ospf6_zebra_is_redistribute (type))
hassoe26bbeb2003-05-25 21:39:29 +0000776 continue;
777
hasso508e53e2004-05-18 18:57:06 +0000778 if (ospf6->rmap[type].name)
779 vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
780 ZROUTE_NAME (type), ospf6->rmap[type].name,
781 (ospf6->rmap[type].map ? "" : " (not found !)"),
hasso049207c2004-08-04 20:02:13 +0000782 VNL);
paul718e3742002-12-13 20:15:29 +0000783 else
hasso508e53e2004-05-18 18:57:06 +0000784 vty_out (vty, " %d: %s%s", nroute[type],
hasso049207c2004-08-04 20:02:13 +0000785 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000786 }
hasso049207c2004-08-04 20:02:13 +0000787 vty_out (vty, "Total %d routes%s", total, VNL);
hasso508e53e2004-05-18 18:57:06 +0000788}
paul718e3742002-12-13 20:15:29 +0000789
paul718e3742002-12-13 20:15:29 +0000790
hasso508e53e2004-05-18 18:57:06 +0000791
792/* Routemap Functions */
793route_map_result_t
794ospf6_routemap_rule_match_address_prefixlist (void *rule,
795 struct prefix *prefix,
796 route_map_object_t type,
797 void *object)
798{
799 struct prefix_list *plist;
paul718e3742002-12-13 20:15:29 +0000800
hasso508e53e2004-05-18 18:57:06 +0000801 if (type != RMAP_OSPF6)
802 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000803
hasso508e53e2004-05-18 18:57:06 +0000804 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
805 if (plist == NULL)
806 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000807
hasso508e53e2004-05-18 18:57:06 +0000808 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
809 RMAP_NOMATCH : RMAP_MATCH);
810}
paul718e3742002-12-13 20:15:29 +0000811
hasso508e53e2004-05-18 18:57:06 +0000812void *
paul0c083ee2004-10-10 12:54:58 +0000813ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000814{
815 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000816}
817
818void
hasso508e53e2004-05-18 18:57:06 +0000819ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000820{
hasso508e53e2004-05-18 18:57:06 +0000821 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
822}
paul718e3742002-12-13 20:15:29 +0000823
hasso508e53e2004-05-18 18:57:06 +0000824struct route_map_rule_cmd
825ospf6_routemap_rule_match_address_prefixlist_cmd =
826{
827 "ipv6 address prefix-list",
828 ospf6_routemap_rule_match_address_prefixlist,
829 ospf6_routemap_rule_match_address_prefixlist_compile,
830 ospf6_routemap_rule_match_address_prefixlist_free,
831};
hassoe26bbeb2003-05-25 21:39:29 +0000832
hasso508e53e2004-05-18 18:57:06 +0000833route_map_result_t
834ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
835 route_map_object_t type, void *object)
836{
837 char *metric_type = rule;
838 struct ospf6_route *route = object;
hassoe26bbeb2003-05-25 21:39:29 +0000839
hasso508e53e2004-05-18 18:57:06 +0000840 if (type != RMAP_OSPF6)
841 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000842
hasso508e53e2004-05-18 18:57:06 +0000843 if (strcmp (metric_type, "type-2") == 0)
844 route->path.metric_type = 2;
paul718e3742002-12-13 20:15:29 +0000845 else
hasso508e53e2004-05-18 18:57:06 +0000846 route->path.metric_type = 1;
paul718e3742002-12-13 20:15:29 +0000847
hasso508e53e2004-05-18 18:57:06 +0000848 return RMAP_OKAY;
849}
paul718e3742002-12-13 20:15:29 +0000850
hasso508e53e2004-05-18 18:57:06 +0000851void *
paul0c083ee2004-10-10 12:54:58 +0000852ospf6_routemap_rule_set_metric_type_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000853{
854 if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
855 return NULL;
856 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000857}
858
859void
hasso508e53e2004-05-18 18:57:06 +0000860ospf6_routemap_rule_set_metric_type_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000861{
hasso508e53e2004-05-18 18:57:06 +0000862 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
863}
paul718e3742002-12-13 20:15:29 +0000864
hasso508e53e2004-05-18 18:57:06 +0000865struct route_map_rule_cmd
866ospf6_routemap_rule_set_metric_type_cmd =
867{
868 "metric-type",
869 ospf6_routemap_rule_set_metric_type,
870 ospf6_routemap_rule_set_metric_type_compile,
871 ospf6_routemap_rule_set_metric_type_free,
872};
paul718e3742002-12-13 20:15:29 +0000873
hasso508e53e2004-05-18 18:57:06 +0000874route_map_result_t
875ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
876 route_map_object_t type, void *object)
877{
878 char *metric = rule;
879 struct ospf6_route *route = object;
paul718e3742002-12-13 20:15:29 +0000880
hasso508e53e2004-05-18 18:57:06 +0000881 if (type != RMAP_OSPF6)
882 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000883
hasso508e53e2004-05-18 18:57:06 +0000884 route->path.cost = atoi (metric);
885 return RMAP_OKAY;
886}
paul718e3742002-12-13 20:15:29 +0000887
hasso508e53e2004-05-18 18:57:06 +0000888void *
paul0c083ee2004-10-10 12:54:58 +0000889ospf6_routemap_rule_set_metric_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000890{
891 u_int32_t metric;
892 char *endp;
893 metric = strtoul (arg, &endp, 0);
894 if (metric > LS_INFINITY || *endp != '\0')
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_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000901{
hasso508e53e2004-05-18 18:57:06 +0000902 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
903}
904
905struct route_map_rule_cmd
906ospf6_routemap_rule_set_metric_cmd =
907{
908 "metric",
909 ospf6_routemap_rule_set_metric,
910 ospf6_routemap_rule_set_metric_compile,
911 ospf6_routemap_rule_set_metric_free,
912};
913
914route_map_result_t
915ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
916 route_map_object_t type, void *object)
917{
918 char *forwarding = rule;
919 struct ospf6_route *route = object;
920 struct ospf6_external_info *info = route->route_option;
921
922 if (type != RMAP_OSPF6)
923 return RMAP_OKAY;
924
925 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
926 {
927 memset (&info->forwarding, 0, sizeof (struct in6_addr));
928 return RMAP_ERROR;
929 }
930
931 return RMAP_OKAY;
932}
933
934void *
paul0c083ee2004-10-10 12:54:58 +0000935ospf6_routemap_rule_set_forwarding_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000936{
937 struct in6_addr a;
938 if (inet_pton (AF_INET6, arg, &a) != 1)
939 return NULL;
940 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
941}
942
943void
944ospf6_routemap_rule_set_forwarding_free (void *rule)
945{
946 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
947}
948
949struct route_map_rule_cmd
950ospf6_routemap_rule_set_forwarding_cmd =
951{
952 "forwarding-address",
953 ospf6_routemap_rule_set_forwarding,
954 ospf6_routemap_rule_set_forwarding_compile,
955 ospf6_routemap_rule_set_forwarding_free,
956};
957
958int
959route_map_command_status (struct vty *vty, int ret)
960{
961 if (! ret)
962 return CMD_SUCCESS;
963
964 switch (ret)
965 {
966 case RMAP_RULE_MISSING:
hasso049207c2004-08-04 20:02:13 +0000967 vty_out (vty, "Can't find rule.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000968 break;
969 case RMAP_COMPILE_ERROR:
hasso049207c2004-08-04 20:02:13 +0000970 vty_out (vty, "Argument is malformed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000971 break;
972 default:
hasso049207c2004-08-04 20:02:13 +0000973 vty_out (vty, "route-map add set failed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000974 break;
975 }
976 return CMD_WARNING;
977}
978
979/* add "match address" */
980DEFUN (ospf6_routemap_match_address_prefixlist,
981 ospf6_routemap_match_address_prefixlist_cmd,
982 "match ipv6 address prefix-list WORD",
983 "Match values\n"
984 IPV6_STR
985 "Match address of route\n"
986 "Match entries of prefix-lists\n"
987 "IPv6 prefix-list name\n")
988{
989 int ret = route_map_add_match ((struct route_map_index *) vty->index,
990 "ipv6 address prefix-list", argv[0]);
991 return route_map_command_status (vty, ret);
992}
993
994/* delete "match address" */
995DEFUN (ospf6_routemap_no_match_address_prefixlist,
996 ospf6_routemap_no_match_address_prefixlist_cmd,
997 "no match ipv6 address prefix-list WORD",
998 NO_STR
999 "Match values\n"
1000 IPV6_STR
1001 "Match address of route\n"
1002 "Match entries of prefix-lists\n"
1003 "IPv6 prefix-list name\n")
1004{
1005 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1006 "ipv6 address prefix-list", argv[0]);
1007 return route_map_command_status (vty, ret);
1008}
1009
1010/* add "set metric-type" */
1011DEFUN (ospf6_routemap_set_metric_type,
1012 ospf6_routemap_set_metric_type_cmd,
1013 "set metric-type (type-1|type-2)",
1014 "Set value\n"
1015 "Type of metric\n"
1016 "OSPF6 external type 1 metric\n"
1017 "OSPF6 external type 2 metric\n")
1018{
1019 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1020 "metric-type", argv[0]);
1021 return route_map_command_status (vty, ret);
1022}
1023
1024/* delete "set metric-type" */
1025DEFUN (ospf6_routemap_no_set_metric_type,
1026 ospf6_routemap_no_set_metric_type_cmd,
1027 "no set metric-type (type-1|type-2)",
1028 NO_STR
1029 "Set value\n"
1030 "Type of metric\n"
1031 "OSPF6 external type 1 metric\n"
1032 "OSPF6 external type 2 metric\n")
1033{
1034 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1035 "metric-type", argv[0]);
1036 return route_map_command_status (vty, ret);
1037}
1038
1039/* add "set metric" */
1040DEFUN (set_metric,
1041 set_metric_cmd,
1042 "set metric <0-4294967295>",
1043 "Set value\n"
1044 "Metric value\n"
1045 "Metric value\n")
1046{
1047 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1048 "metric", argv[0]);
1049 return route_map_command_status (vty, ret);
1050}
1051
1052/* delete "set metric" */
1053DEFUN (no_set_metric,
1054 no_set_metric_cmd,
1055 "no set metric <0-4294967295>",
1056 NO_STR
1057 "Set value\n"
1058 "Metric\n"
1059 "METRIC value\n")
1060{
1061 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1062 "metric", argv[0]);
1063 return route_map_command_status (vty, ret);
1064}
1065
1066/* add "set forwarding-address" */
1067DEFUN (ospf6_routemap_set_forwarding,
1068 ospf6_routemap_set_forwarding_cmd,
1069 "set forwarding-address X:X::X:X",
1070 "Set value\n"
1071 "Forwarding Address\n"
1072 "IPv6 Address\n")
1073{
1074 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1075 "forwarding-address", argv[0]);
1076 return route_map_command_status (vty, ret);
1077}
1078
1079/* delete "set forwarding-address" */
1080DEFUN (ospf6_routemap_no_set_forwarding,
1081 ospf6_routemap_no_set_forwarding_cmd,
1082 "no set forwarding-address X:X::X:X",
1083 NO_STR
1084 "Set value\n"
1085 "Forwarding Address\n"
1086 "IPv6 Address\n")
1087{
1088 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1089 "forwarding-address", argv[0]);
1090 return route_map_command_status (vty, ret);
1091}
1092
1093void
1094ospf6_routemap_init ()
1095{
1096 route_map_init ();
1097 route_map_init_vty ();
1098 route_map_add_hook (ospf6_asbr_routemap_update);
1099 route_map_delete_hook (ospf6_asbr_routemap_update);
1100
1101 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
1102 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
1103 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
1104 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
1105
1106 /* Match address prefix-list */
1107 install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
1108 install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
1109
1110 /* ASE Metric Type (e.g. Type-1/Type-2) */
1111 install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
1112 install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
1113
1114 /* ASE Metric */
1115 install_element (RMAP_NODE, &set_metric_cmd);
1116 install_element (RMAP_NODE, &no_set_metric_cmd);
1117
1118 /* ASE Metric */
1119 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
1120 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
1121}
1122
1123
1124/* Display functions */
1125int
1126ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
1127{
1128 struct ospf6_as_external_lsa *external;
paul718e3742002-12-13 20:15:29 +00001129 char buf[64];
hasso508e53e2004-05-18 18:57:06 +00001130 struct in6_addr in6, *forwarding;
paul718e3742002-12-13 20:15:29 +00001131
1132 assert (lsa->header);
hasso508e53e2004-05-18 18:57:06 +00001133 external = (struct ospf6_as_external_lsa *)
1134 OSPF6_LSA_HEADER_END (lsa->header);
paul718e3742002-12-13 20:15:29 +00001135
1136 /* bits */
hasso508e53e2004-05-18 18:57:06 +00001137 snprintf (buf, sizeof (buf), "%c%c%c",
1138 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
1139 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
1140 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
paul718e3742002-12-13 20:15:29 +00001141
hasso049207c2004-08-04 20:02:13 +00001142 vty_out (vty, " Bits: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +00001143 vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
hasso049207c2004-08-04 20:02:13 +00001144 VNL);
paul718e3742002-12-13 20:15:29 +00001145
hasso508e53e2004-05-18 18:57:06 +00001146 ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1147 buf, sizeof (buf));
1148 vty_out (vty, " Prefix Options: %s%s", buf,
hasso049207c2004-08-04 20:02:13 +00001149 VNL);
paul718e3742002-12-13 20:15:29 +00001150
1151 vty_out (vty, " Referenced LSType: %d%s",
hasso508e53e2004-05-18 18:57:06 +00001152 ntohs (external->prefix.prefix_refer_lstype),
hasso049207c2004-08-04 20:02:13 +00001153 VNL);
paul718e3742002-12-13 20:15:29 +00001154
hasso508e53e2004-05-18 18:57:06 +00001155 ospf6_prefix_in6_addr (&in6, &external->prefix);
paul718e3742002-12-13 20:15:29 +00001156 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
hasso508e53e2004-05-18 18:57:06 +00001157 vty_out (vty, " Prefix: %s/%d%s", buf,
hasso049207c2004-08-04 20:02:13 +00001158 external->prefix.prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +00001159
1160 /* Forwarding-Address */
1161 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
1162 {
hasso508e53e2004-05-18 18:57:06 +00001163 forwarding = (struct in6_addr *)
1164 ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
1165 OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
1166 inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +00001167 vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
paul718e3742002-12-13 20:15:29 +00001168 }
1169
1170 return 0;
1171}
1172
1173void
hasso508e53e2004-05-18 18:57:06 +00001174ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +00001175{
hasso508e53e2004-05-18 18:57:06 +00001176 struct ospf6_external_info *info = route->route_option;
1177 char prefix[64], id[16], forwarding[64];
1178 u_int32_t tmp_id;
1179
1180 prefix2str (&route->prefix, prefix, sizeof (prefix));
1181 tmp_id = ntohl (info->id);
1182 inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
1183 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
1184 inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
1185 else
1186 snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
1187 route->nexthop[0].ifindex);
1188
ajsf52d13c2005-10-01 17:38:06 +00001189 vty_out (vty, "%c %-32s %-15s type-%d %5lu %s%s",
1190 zebra_route_char(info->type),
hasso508e53e2004-05-18 18:57:06 +00001191 prefix, id, route->path.metric_type,
1192 (u_long) (route->path.metric_type == 2 ?
1193 route->path.cost_e2 : route->path.cost),
hasso049207c2004-08-04 20:02:13 +00001194 forwarding, VNL);
paul718e3742002-12-13 20:15:29 +00001195}
1196
hasso508e53e2004-05-18 18:57:06 +00001197DEFUN (show_ipv6_ospf6_redistribute,
1198 show_ipv6_ospf6_redistribute_cmd,
1199 "show ipv6 ospf6 redistribute",
paul718e3742002-12-13 20:15:29 +00001200 SHOW_STR
1201 IP6_STR
paul718e3742002-12-13 20:15:29 +00001202 OSPF6_STR
1203 "redistributing External information\n"
1204 )
1205{
hasso508e53e2004-05-18 18:57:06 +00001206 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +00001207
hasso508e53e2004-05-18 18:57:06 +00001208 ospf6_redistribute_show_config (vty);
1209
1210 for (route = ospf6_route_head (ospf6->external_table); route;
1211 route = ospf6_route_next (route))
1212 ospf6_asbr_external_route_show (vty, route);
1213
paul718e3742002-12-13 20:15:29 +00001214 return CMD_SUCCESS;
1215}
1216
hasso6452df02004-08-15 05:52:07 +00001217struct ospf6_lsa_handler as_external_handler =
hasso508e53e2004-05-18 18:57:06 +00001218{
hasso6452df02004-08-15 05:52:07 +00001219 OSPF6_LSTYPE_AS_EXTERNAL,
1220 "AS-External",
1221 ospf6_as_external_lsa_show
1222};
hasso508e53e2004-05-18 18:57:06 +00001223
paul718e3742002-12-13 20:15:29 +00001224void
1225ospf6_asbr_init ()
1226{
hasso508e53e2004-05-18 18:57:06 +00001227 ospf6_routemap_init ();
paul718e3742002-12-13 20:15:29 +00001228
hasso6452df02004-08-15 05:52:07 +00001229 ospf6_install_lsa_handler (&as_external_handler);
paul718e3742002-12-13 20:15:29 +00001230
hasso508e53e2004-05-18 18:57:06 +00001231 install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
1232 install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
1233
paul718e3742002-12-13 20:15:29 +00001234 install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
1235 install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
1236 install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
1237}
1238
1239
hasso508e53e2004-05-18 18:57:06 +00001240DEFUN (debug_ospf6_asbr,
1241 debug_ospf6_asbr_cmd,
1242 "debug ospf6 asbr",
1243 DEBUG_STR
1244 OSPF6_STR
1245 "Debug OSPFv3 ASBR function\n"
1246 )
1247{
1248 OSPF6_DEBUG_ASBR_ON ();
1249 return CMD_SUCCESS;
1250}
1251
1252DEFUN (no_debug_ospf6_asbr,
1253 no_debug_ospf6_asbr_cmd,
1254 "no debug ospf6 asbr",
1255 NO_STR
1256 DEBUG_STR
1257 OSPF6_STR
1258 "Debug OSPFv3 ASBR function\n"
1259 )
1260{
1261 OSPF6_DEBUG_ASBR_OFF ();
1262 return CMD_SUCCESS;
1263}
1264
1265int
1266config_write_ospf6_debug_asbr (struct vty *vty)
1267{
1268 if (IS_OSPF6_DEBUG_ASBR)
hasso049207c2004-08-04 20:02:13 +00001269 vty_out (vty, "debug ospf6 asbr%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001270 return 0;
1271}
1272
1273void
1274install_element_ospf6_debug_asbr ()
1275{
1276 install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
1277 install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
1278 install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
1279 install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
1280}
1281
1282