blob: c9fc5c1c4a7891dc19fba59b291ae25aeb8a3a9e [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
paul0c083ee2004-10-10 12:54:58 +000053const char *zroute_name[] =
hasso508e53e2004-05-18 18:57:06 +000054{ "system", "kernel", "connected", "static",
paul8bfb0cb2005-01-25 01:19:28 +000055 "rip", "ripng", "ospf", "ospf6", "isis", "bgp", "hsls", "unknown" };
hasso508e53e2004-05-18 18:57:06 +000056
paul0c083ee2004-10-10 12:54:58 +000057const char *zroute_abname[] =
paul8bfb0cb2005-01-25 01:19:28 +000058{ "X", "K", "C", "S", "R", "R", "O", "O", "I", "B", "H", "?" };
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
hasso1e058382004-09-01 21:36:14 +000084 if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +000085 {
86 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +000087 zlog_debug ("Originate AS-External-LSA for %s", buf);
hasso508e53e2004-05-18 18:57:06 +000088 }
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
hasso1e058382004-09-01 21:36:14 +0000178 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000179 zlog_debug ("Calculate AS-External route for %s", lsa->name);
hasso508e53e2004-05-18 18:57:06 +0000180
181 if (lsa->header->adv_router == ospf6->router_id)
182 {
hasso1e058382004-09-01 21:36:14 +0000183 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000184 zlog_debug ("Ignore self-originated AS-External-LSA");
hasso508e53e2004-05-18 18:57:06 +0000185 return;
186 }
187
188 if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
189 {
hasso1e058382004-09-01 21:36:14 +0000190 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000191 zlog_debug ("Ignore LSA with LSInfinity Metric");
hasso508e53e2004-05-18 18:57:06 +0000192 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);
hasso63069ad2004-09-02 13:01:01 +0000197 if (asbr_entry == NULL ||
198 ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))
hasso508e53e2004-05-18 18:57:06 +0000199 {
hasso1e058382004-09-01 21:36:14 +0000200 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000201 {
202 prefix2str (&asbr_id, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000203 zlog_debug ("ASBR entry not found: %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000204 }
205 return;
206 }
207
208 route = ospf6_route_create ();
209 route->type = OSPF6_DEST_TYPE_NETWORK;
210 route->prefix.family = AF_INET6;
211 route->prefix.prefixlen = external->prefix.prefix_length;
212 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
213
214 route->path.area_id = asbr_entry->path.area_id;
215 route->path.origin.type = lsa->header->type;
216 route->path.origin.id = lsa->header->id;
217 route->path.origin.adv_router = lsa->header->adv_router;
218
219 route->path.prefix_options = external->prefix.prefix_options;
220 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
221 {
222 route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
223 route->path.metric_type = 2;
224 route->path.cost = asbr_entry->path.cost;
225 route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
226 }
227 else
228 {
229 route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
230 route->path.metric_type = 1;
231 route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
232 route->path.cost_e2 = 0;
233 }
234
235 for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
236 ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
237
hasso1e058382004-09-01 21:36:14 +0000238 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000239 {
240 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000241 zlog_debug ("AS-External route add: %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000242 }
243
244 ospf6_route_add (route, ospf6->route_table);
245}
246
247void
248ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
249{
250 struct ospf6_as_external_lsa *external;
251 struct prefix prefix;
252 struct ospf6_route *route;
253 char buf[64];
254
255 external = (struct ospf6_as_external_lsa *)
256 OSPF6_LSA_HEADER_END (lsa->header);
257
hasso1e058382004-09-01 21:36:14 +0000258 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000259 zlog_debug ("Withdraw AS-External route for %s", lsa->name);
hasso508e53e2004-05-18 18:57:06 +0000260
261 if (lsa->header->adv_router == ospf6->router_id)
262 {
hasso1e058382004-09-01 21:36:14 +0000263 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000264 zlog_debug ("Ignore self-originated AS-External-LSA");
hasso508e53e2004-05-18 18:57:06 +0000265 return;
266 }
267
268 memset (&prefix, 0, sizeof (struct prefix));
269 prefix.family = AF_INET6;
270 prefix.prefixlen = external->prefix.prefix_length;
271 ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
272
273 route = ospf6_route_lookup (&prefix, ospf6->route_table);
274 if (route == NULL)
275 {
hasso1e058382004-09-01 21:36:14 +0000276 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000277 {
278 prefix2str (&prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000279 zlog_debug ("AS-External route %s not found", buf);
hasso508e53e2004-05-18 18:57:06 +0000280 }
281 return;
282 }
283
284 for (ospf6_route_lock (route);
285 route && ospf6_route_is_prefix (&prefix, route);
286 route = ospf6_route_next (route))
287 {
288 if (route->type != OSPF6_DEST_TYPE_NETWORK)
289 continue;
290 if (route->path.origin.type != lsa->header->type)
291 continue;
292 if (route->path.origin.id != lsa->header->id)
293 continue;
294 if (route->path.origin.adv_router != lsa->header->adv_router)
295 continue;
296
hasso1e058382004-09-01 21:36:14 +0000297 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000298 {
299 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000300 zlog_debug ("AS-External route remove: %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000301 }
302 ospf6_route_remove (route, ospf6->route_table);
303 }
304}
305
306void
307ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
308{
309 char buf[64];
310 struct ospf6_lsa *lsa;
311 u_int16_t type;
312 u_int32_t router;
313
hasso1e058382004-09-01 21:36:14 +0000314 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000315 {
316 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000317 zlog_debug ("New ASBR %s found", buf);
hasso508e53e2004-05-18 18:57:06 +0000318 }
319
320 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
321 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
322 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
323 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
324 {
325 if (! OSPF6_LSA_IS_MAXAGE (lsa))
326 ospf6_asbr_lsa_add (lsa);
327 }
328
hasso1e058382004-09-01 21:36:14 +0000329 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000330 {
331 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000332 zlog_debug ("Calculation for new ASBR %s done", buf);
hasso508e53e2004-05-18 18:57:06 +0000333 }
334}
335
336void
337ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
338{
339 char buf[64];
340 struct ospf6_lsa *lsa;
341 u_int16_t type;
342 u_int32_t router;
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 ("ASBR %s disappeared", buf);
hasso508e53e2004-05-18 18:57:06 +0000348 }
349
350 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
351 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
352 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
353 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
354 ospf6_asbr_lsa_remove (lsa);
355
hasso1e058382004-09-01 21:36:14 +0000356 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000357 {
358 ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000359 zlog_debug ("Calculation for old ASBR %s done", buf);
hasso508e53e2004-05-18 18:57:06 +0000360 }
361}
362
363
364
paul718e3742002-12-13 20:15:29 +0000365/* redistribute function */
hasso508e53e2004-05-18 18:57:06 +0000366
paul718e3742002-12-13 20:15:29 +0000367void
paul0c083ee2004-10-10 12:54:58 +0000368ospf6_asbr_routemap_set (int type, const char *mapname)
paul718e3742002-12-13 20:15:29 +0000369{
hasso508e53e2004-05-18 18:57:06 +0000370 if (ospf6->rmap[type].name)
371 free (ospf6->rmap[type].name);
372 ospf6->rmap[type].name = strdup (mapname);
373 ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
paul718e3742002-12-13 20:15:29 +0000374}
375
376void
377ospf6_asbr_routemap_unset (int type)
378{
hasso508e53e2004-05-18 18:57:06 +0000379 if (ospf6->rmap[type].name)
380 free (ospf6->rmap[type].name);
381 ospf6->rmap[type].name = NULL;
382 ospf6->rmap[type].map = NULL;
paul718e3742002-12-13 20:15:29 +0000383}
384
385void
paul0c083ee2004-10-10 12:54:58 +0000386ospf6_asbr_routemap_update (const char *mapname)
paul718e3742002-12-13 20:15:29 +0000387{
hasso508e53e2004-05-18 18:57:06 +0000388 int type;
389
390 if (ospf6 == NULL)
391 return;
392
393 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000394 {
hasso508e53e2004-05-18 18:57:06 +0000395 if (ospf6->rmap[type].name)
396 ospf6->rmap[type].map =
397 route_map_lookup_by_name (ospf6->rmap[type].name);
paul718e3742002-12-13 20:15:29 +0000398 else
hasso508e53e2004-05-18 18:57:06 +0000399 ospf6->rmap[type].map = NULL;
400 }
401}
402
403int
404ospf6_asbr_is_asbr (struct ospf6 *o)
405{
406 return o->external_table->count;
407}
408
409void
410ospf6_asbr_redistribute_set (int type)
411{
412 ospf6_zebra_redistribute (type);
413}
414
415void
416ospf6_asbr_redistribute_unset (int type)
417{
418 struct ospf6_route *route;
419 struct ospf6_external_info *info;
420
421 ospf6_zebra_no_redistribute (type);
422
423 for (route = ospf6_route_head (ospf6->external_table); route;
424 route = ospf6_route_next (route))
425 {
426 info = route->route_option;
427 if (info->type != type)
428 continue;
429
430 ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
431 &route->prefix);
432 }
433}
434
435void
436ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
437 u_int nexthop_num, struct in6_addr *nexthop)
438{
439 int ret;
440 struct ospf6_route troute;
441 struct ospf6_external_info tinfo;
442 struct ospf6_route *route, *match;
443 struct ospf6_external_info *info;
444 struct prefix prefix_id;
445 struct route_node *node;
446 char pbuf[64], ibuf[16];
hasso52dc7ee2004-09-23 19:18:23 +0000447 struct listnode *lnode;
hasso508e53e2004-05-18 18:57:06 +0000448 struct ospf6_area *oa;
449
450 if (! ospf6_zebra_is_redistribute (type))
451 return;
452
453 if (IS_OSPF6_DEBUG_ASBR)
454 {
455 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000456 zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
hasso508e53e2004-05-18 18:57:06 +0000457 }
458
459 /* if route-map was specified but not found, do not advertise */
460 if (ospf6->rmap[type].name)
461 {
462 if (ospf6->rmap[type].map == NULL)
hasso03d52f82004-09-29 00:26:19 +0000463 ospf6_asbr_routemap_update (NULL);
hasso508e53e2004-05-18 18:57:06 +0000464 if (ospf6->rmap[type].map == NULL)
465 {
466 zlog_warn ("route-map \"%s\" not found, suppress redistributing",
467 ospf6->rmap[type].name);
468 return;
469 }
470 }
471
472 /* apply route-map */
473 if (ospf6->rmap[type].map)
474 {
475 memset (&troute, 0, sizeof (troute));
476 memset (&tinfo, 0, sizeof (tinfo));
477 troute.route_option = &tinfo;
478
479 ret = route_map_apply (ospf6->rmap[type].map, prefix,
480 RMAP_OSPF6, &troute);
481 if (ret != RMAP_MATCH)
482 {
483 if (IS_OSPF6_DEBUG_ASBR)
hassoc6487d62004-12-24 06:00:11 +0000484 zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
hasso508e53e2004-05-18 18:57:06 +0000485 return;
486 }
487 }
488
489 match = ospf6_route_lookup (prefix, ospf6->external_table);
490 if (match)
491 {
492 info = match->route_option;
493
494 /* copy result of route-map */
495 if (ospf6->rmap[type].map)
496 {
497 if (troute.path.metric_type)
498 match->path.metric_type = troute.path.metric_type;
499 if (troute.path.cost)
500 match->path.cost = troute.path.cost;
501 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
502 memcpy (&info->forwarding, &tinfo.forwarding,
503 sizeof (struct in6_addr));
504 }
505
506 info->type = type;
507 match->nexthop[0].ifindex = ifindex;
508 if (nexthop_num && nexthop)
509 memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
510
511 /* create/update binding in external_id_table */
512 prefix_id.family = AF_INET;
513 prefix_id.prefixlen = 32;
514 prefix_id.u.prefix4.s_addr = htonl (info->id);
515 node = route_node_get (ospf6->external_id_table, &prefix_id);
516 node->info = match;
517
518 if (IS_OSPF6_DEBUG_ASBR)
519 {
520 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000521 zlog_debug ("Advertise as AS-External Id:%s", ibuf);
hasso508e53e2004-05-18 18:57:06 +0000522 }
523
hasso3b687352004-08-19 06:56:53 +0000524 match->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000525 ospf6_as_external_lsa_originate (match);
hasso508e53e2004-05-18 18:57:06 +0000526 return;
527 }
528
529 /* create new entry */
530 route = ospf6_route_create ();
531 route->type = OSPF6_DEST_TYPE_NETWORK;
532 memcpy (&route->prefix, prefix, sizeof (struct prefix));
533
534 info = (struct ospf6_external_info *)
535 XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
536 memset (info, 0, sizeof (struct ospf6_external_info));
537 route->route_option = info;
538 info->id = ospf6->external_id++;
539
540 /* copy result of route-map */
541 if (ospf6->rmap[type].map)
542 {
543 if (troute.path.metric_type)
544 route->path.metric_type = troute.path.metric_type;
545 if (troute.path.cost)
546 route->path.cost = troute.path.cost;
547 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
548 memcpy (&info->forwarding, &tinfo.forwarding,
549 sizeof (struct in6_addr));
550 }
551
552 info->type = type;
553 route->nexthop[0].ifindex = ifindex;
554 if (nexthop_num && nexthop)
555 memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
556
557 /* create/update binding in external_id_table */
558 prefix_id.family = AF_INET;
559 prefix_id.prefixlen = 32;
560 prefix_id.u.prefix4.s_addr = htonl (info->id);
561 node = route_node_get (ospf6->external_id_table, &prefix_id);
562 node->info = route;
563
564 route = ospf6_route_add (route, ospf6->external_table);
565 route->route_option = info;
566
567 if (IS_OSPF6_DEBUG_ASBR)
568 {
569 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000570 zlog_debug ("Advertise as AS-External Id:%s", ibuf);
hasso508e53e2004-05-18 18:57:06 +0000571 }
572
hasso3b687352004-08-19 06:56:53 +0000573 route->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000574 ospf6_as_external_lsa_originate (route);
hasso508e53e2004-05-18 18:57:06 +0000575
576 /* Router-Bit (ASBR Flag) may have to be updated */
577 for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode))
578 {
579 oa = (struct ospf6_area *) getdata (lnode);
580 OSPF6_ROUTER_LSA_SCHEDULE (oa);
581 }
582}
583
584void
585ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
586{
587 struct ospf6_route *match;
588 struct ospf6_external_info *info = NULL;
589 struct route_node *node;
590 struct ospf6_lsa *lsa;
591 struct prefix prefix_id;
592 char pbuf[64], ibuf[16];
hasso52dc7ee2004-09-23 19:18:23 +0000593 struct listnode *lnode;
hasso508e53e2004-05-18 18:57:06 +0000594 struct ospf6_area *oa;
595
596 match = ospf6_route_lookup (prefix, ospf6->external_table);
597 if (match == NULL)
598 {
599 if (IS_OSPF6_DEBUG_ASBR)
600 {
601 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000602 zlog_debug ("No such route %s to withdraw", pbuf);
hasso508e53e2004-05-18 18:57:06 +0000603 }
604 return;
605 }
606
607 info = match->route_option;
608 assert (info);
609
610 if (info->type != type)
611 {
612 if (IS_OSPF6_DEBUG_ASBR)
613 {
614 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000615 zlog_debug ("Original protocol mismatch: %s", pbuf);
hasso508e53e2004-05-18 18:57:06 +0000616 }
617 return;
618 }
619
620 if (IS_OSPF6_DEBUG_ASBR)
621 {
622 prefix2str (prefix, pbuf, sizeof (pbuf));
623 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000624 zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
hasso508e53e2004-05-18 18:57:06 +0000625 }
626
627 lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
628 htonl (info->id), ospf6->router_id, ospf6->lsdb);
629 if (lsa)
hasso6452df02004-08-15 05:52:07 +0000630 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000631
632 /* remove binding in external_id_table */
633 prefix_id.family = AF_INET;
634 prefix_id.prefixlen = 32;
635 prefix_id.u.prefix4.s_addr = htonl (info->id);
636 node = route_node_lookup (ospf6->external_id_table, &prefix_id);
637 assert (node);
638 node->info = NULL;
639 route_unlock_node (node);
640
641 ospf6_route_remove (match, ospf6->external_table);
642 XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
643
644 /* Router-Bit (ASBR Flag) may have to be updated */
645 for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode))
646 {
647 oa = (struct ospf6_area *) getdata (lnode);
648 OSPF6_ROUTER_LSA_SCHEDULE (oa);
paul718e3742002-12-13 20:15:29 +0000649 }
650}
651
652DEFUN (ospf6_redistribute,
653 ospf6_redistribute_cmd,
654 "redistribute (static|kernel|connected|ripng|bgp)",
655 "Redistribute\n"
656 "Static route\n"
657 "Kernel route\n"
658 "Connected route\n"
659 "RIPng route\n"
660 "BGP route\n"
661 )
662{
663 int type = 0;
664
665 if (strncmp (argv[0], "sta", 3) == 0)
666 type = ZEBRA_ROUTE_STATIC;
667 else if (strncmp (argv[0], "ker", 3) == 0)
668 type = ZEBRA_ROUTE_KERNEL;
669 else if (strncmp (argv[0], "con", 3) == 0)
670 type = ZEBRA_ROUTE_CONNECT;
671 else if (strncmp (argv[0], "rip", 3) == 0)
672 type = ZEBRA_ROUTE_RIPNG;
673 else if (strncmp (argv[0], "bgp", 3) == 0)
674 type = ZEBRA_ROUTE_BGP;
675
hasso508e53e2004-05-18 18:57:06 +0000676 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000677 ospf6_asbr_routemap_unset (type);
hasso508e53e2004-05-18 18:57:06 +0000678 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000679 return CMD_SUCCESS;
680}
681
682DEFUN (ospf6_redistribute_routemap,
683 ospf6_redistribute_routemap_cmd,
684 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
685 "Redistribute\n"
686 "Static routes\n"
687 "Kernel route\n"
688 "Connected route\n"
689 "RIPng route\n"
690 "BGP route\n"
691 "Route map reference\n"
692 "Route map name\n"
693 )
694{
695 int type = 0;
696
697 if (strncmp (argv[0], "sta", 3) == 0)
698 type = ZEBRA_ROUTE_STATIC;
699 else if (strncmp (argv[0], "ker", 3) == 0)
700 type = ZEBRA_ROUTE_KERNEL;
701 else if (strncmp (argv[0], "con", 3) == 0)
702 type = ZEBRA_ROUTE_CONNECT;
703 else if (strncmp (argv[0], "rip", 3) == 0)
704 type = ZEBRA_ROUTE_RIPNG;
705 else if (strncmp (argv[0], "bgp", 3) == 0)
706 type = ZEBRA_ROUTE_BGP;
707
hasso508e53e2004-05-18 18:57:06 +0000708 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000709 ospf6_asbr_routemap_set (type, argv[1]);
hasso508e53e2004-05-18 18:57:06 +0000710 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000711 return CMD_SUCCESS;
712}
713
714DEFUN (no_ospf6_redistribute,
715 no_ospf6_redistribute_cmd,
716 "no redistribute (static|kernel|connected|ripng|bgp)",
717 NO_STR
718 "Redistribute\n"
719 "Static route\n"
720 "Kernel route\n"
721 "Connected route\n"
722 "RIPng route\n"
723 "BGP route\n"
724 )
725{
726 int type = 0;
paul718e3742002-12-13 20:15:29 +0000727
728 if (strncmp (argv[0], "sta", 3) == 0)
729 type = ZEBRA_ROUTE_STATIC;
730 else if (strncmp (argv[0], "ker", 3) == 0)
731 type = ZEBRA_ROUTE_KERNEL;
732 else if (strncmp (argv[0], "con", 3) == 0)
733 type = ZEBRA_ROUTE_CONNECT;
734 else if (strncmp (argv[0], "rip", 3) == 0)
735 type = ZEBRA_ROUTE_RIPNG;
736 else if (strncmp (argv[0], "bgp", 3) == 0)
737 type = ZEBRA_ROUTE_BGP;
738
hasso508e53e2004-05-18 18:57:06 +0000739 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000740 ospf6_asbr_routemap_unset (type);
741
paul718e3742002-12-13 20:15:29 +0000742 return CMD_SUCCESS;
743}
744
paul718e3742002-12-13 20:15:29 +0000745int
746ospf6_redistribute_config_write (struct vty *vty)
747{
hasso508e53e2004-05-18 18:57:06 +0000748 int type;
paul718e3742002-12-13 20:15:29 +0000749
hasso508e53e2004-05-18 18:57:06 +0000750 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000751 {
hasso508e53e2004-05-18 18:57:06 +0000752 if (type == ZEBRA_ROUTE_OSPF6)
753 continue;
754 if (! ospf6_zebra_is_redistribute (type))
paul718e3742002-12-13 20:15:29 +0000755 continue;
756
hasso508e53e2004-05-18 18:57:06 +0000757 if (ospf6->rmap[type].name)
paul718e3742002-12-13 20:15:29 +0000758 vty_out (vty, " redistribute %s route-map %s%s",
hasso049207c2004-08-04 20:02:13 +0000759 ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
paul718e3742002-12-13 20:15:29 +0000760 else
761 vty_out (vty, " redistribute %s%s",
hasso049207c2004-08-04 20:02:13 +0000762 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000763 }
764
765 return 0;
766}
767
768void
769ospf6_redistribute_show_config (struct vty *vty)
770{
hasso508e53e2004-05-18 18:57:06 +0000771 int type;
772 int nroute[ZEBRA_ROUTE_MAX];
773 int total;
774 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000775 struct ospf6_external_info *info;
paul718e3742002-12-13 20:15:29 +0000776
hasso508e53e2004-05-18 18:57:06 +0000777 total = 0;
778 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
779 nroute[type] = 0;
780 for (route = ospf6_route_head (ospf6->external_table); route;
781 route = ospf6_route_next (route))
paul718e3742002-12-13 20:15:29 +0000782 {
hasso508e53e2004-05-18 18:57:06 +0000783 info = route->route_option;
784 nroute[info->type]++;
785 total++;
paul718e3742002-12-13 20:15:29 +0000786 }
787
hasso049207c2004-08-04 20:02:13 +0000788 vty_out (vty, "Redistributing External Routes from:%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000789 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000790 {
hasso508e53e2004-05-18 18:57:06 +0000791 if (type == ZEBRA_ROUTE_OSPF6)
792 continue;
793 if (! ospf6_zebra_is_redistribute (type))
hassoe26bbeb2003-05-25 21:39:29 +0000794 continue;
795
hasso508e53e2004-05-18 18:57:06 +0000796 if (ospf6->rmap[type].name)
797 vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
798 ZROUTE_NAME (type), ospf6->rmap[type].name,
799 (ospf6->rmap[type].map ? "" : " (not found !)"),
hasso049207c2004-08-04 20:02:13 +0000800 VNL);
paul718e3742002-12-13 20:15:29 +0000801 else
hasso508e53e2004-05-18 18:57:06 +0000802 vty_out (vty, " %d: %s%s", nroute[type],
hasso049207c2004-08-04 20:02:13 +0000803 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000804 }
hasso049207c2004-08-04 20:02:13 +0000805 vty_out (vty, "Total %d routes%s", total, VNL);
hasso508e53e2004-05-18 18:57:06 +0000806}
paul718e3742002-12-13 20:15:29 +0000807
paul718e3742002-12-13 20:15:29 +0000808
hasso508e53e2004-05-18 18:57:06 +0000809
810/* Routemap Functions */
811route_map_result_t
812ospf6_routemap_rule_match_address_prefixlist (void *rule,
813 struct prefix *prefix,
814 route_map_object_t type,
815 void *object)
816{
817 struct prefix_list *plist;
paul718e3742002-12-13 20:15:29 +0000818
hasso508e53e2004-05-18 18:57:06 +0000819 if (type != RMAP_OSPF6)
820 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000821
hasso508e53e2004-05-18 18:57:06 +0000822 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
823 if (plist == NULL)
824 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000825
hasso508e53e2004-05-18 18:57:06 +0000826 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
827 RMAP_NOMATCH : RMAP_MATCH);
828}
paul718e3742002-12-13 20:15:29 +0000829
hasso508e53e2004-05-18 18:57:06 +0000830void *
paul0c083ee2004-10-10 12:54:58 +0000831ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000832{
833 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000834}
835
836void
hasso508e53e2004-05-18 18:57:06 +0000837ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000838{
hasso508e53e2004-05-18 18:57:06 +0000839 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
840}
paul718e3742002-12-13 20:15:29 +0000841
hasso508e53e2004-05-18 18:57:06 +0000842struct route_map_rule_cmd
843ospf6_routemap_rule_match_address_prefixlist_cmd =
844{
845 "ipv6 address prefix-list",
846 ospf6_routemap_rule_match_address_prefixlist,
847 ospf6_routemap_rule_match_address_prefixlist_compile,
848 ospf6_routemap_rule_match_address_prefixlist_free,
849};
hassoe26bbeb2003-05-25 21:39:29 +0000850
hasso508e53e2004-05-18 18:57:06 +0000851route_map_result_t
852ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
853 route_map_object_t type, void *object)
854{
855 char *metric_type = rule;
856 struct ospf6_route *route = object;
hassoe26bbeb2003-05-25 21:39:29 +0000857
hasso508e53e2004-05-18 18:57:06 +0000858 if (type != RMAP_OSPF6)
859 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000860
hasso508e53e2004-05-18 18:57:06 +0000861 if (strcmp (metric_type, "type-2") == 0)
862 route->path.metric_type = 2;
paul718e3742002-12-13 20:15:29 +0000863 else
hasso508e53e2004-05-18 18:57:06 +0000864 route->path.metric_type = 1;
paul718e3742002-12-13 20:15:29 +0000865
hasso508e53e2004-05-18 18:57:06 +0000866 return RMAP_OKAY;
867}
paul718e3742002-12-13 20:15:29 +0000868
hasso508e53e2004-05-18 18:57:06 +0000869void *
paul0c083ee2004-10-10 12:54:58 +0000870ospf6_routemap_rule_set_metric_type_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000871{
872 if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
873 return NULL;
874 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000875}
876
877void
hasso508e53e2004-05-18 18:57:06 +0000878ospf6_routemap_rule_set_metric_type_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000879{
hasso508e53e2004-05-18 18:57:06 +0000880 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
881}
paul718e3742002-12-13 20:15:29 +0000882
hasso508e53e2004-05-18 18:57:06 +0000883struct route_map_rule_cmd
884ospf6_routemap_rule_set_metric_type_cmd =
885{
886 "metric-type",
887 ospf6_routemap_rule_set_metric_type,
888 ospf6_routemap_rule_set_metric_type_compile,
889 ospf6_routemap_rule_set_metric_type_free,
890};
paul718e3742002-12-13 20:15:29 +0000891
hasso508e53e2004-05-18 18:57:06 +0000892route_map_result_t
893ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
894 route_map_object_t type, void *object)
895{
896 char *metric = rule;
897 struct ospf6_route *route = object;
paul718e3742002-12-13 20:15:29 +0000898
hasso508e53e2004-05-18 18:57:06 +0000899 if (type != RMAP_OSPF6)
900 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000901
hasso508e53e2004-05-18 18:57:06 +0000902 route->path.cost = atoi (metric);
903 return RMAP_OKAY;
904}
paul718e3742002-12-13 20:15:29 +0000905
hasso508e53e2004-05-18 18:57:06 +0000906void *
paul0c083ee2004-10-10 12:54:58 +0000907ospf6_routemap_rule_set_metric_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000908{
909 u_int32_t metric;
910 char *endp;
911 metric = strtoul (arg, &endp, 0);
912 if (metric > LS_INFINITY || *endp != '\0')
913 return NULL;
914 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000915}
916
917void
hasso508e53e2004-05-18 18:57:06 +0000918ospf6_routemap_rule_set_metric_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000919{
hasso508e53e2004-05-18 18:57:06 +0000920 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
921}
922
923struct route_map_rule_cmd
924ospf6_routemap_rule_set_metric_cmd =
925{
926 "metric",
927 ospf6_routemap_rule_set_metric,
928 ospf6_routemap_rule_set_metric_compile,
929 ospf6_routemap_rule_set_metric_free,
930};
931
932route_map_result_t
933ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
934 route_map_object_t type, void *object)
935{
936 char *forwarding = rule;
937 struct ospf6_route *route = object;
938 struct ospf6_external_info *info = route->route_option;
939
940 if (type != RMAP_OSPF6)
941 return RMAP_OKAY;
942
943 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
944 {
945 memset (&info->forwarding, 0, sizeof (struct in6_addr));
946 return RMAP_ERROR;
947 }
948
949 return RMAP_OKAY;
950}
951
952void *
paul0c083ee2004-10-10 12:54:58 +0000953ospf6_routemap_rule_set_forwarding_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000954{
955 struct in6_addr a;
956 if (inet_pton (AF_INET6, arg, &a) != 1)
957 return NULL;
958 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
959}
960
961void
962ospf6_routemap_rule_set_forwarding_free (void *rule)
963{
964 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
965}
966
967struct route_map_rule_cmd
968ospf6_routemap_rule_set_forwarding_cmd =
969{
970 "forwarding-address",
971 ospf6_routemap_rule_set_forwarding,
972 ospf6_routemap_rule_set_forwarding_compile,
973 ospf6_routemap_rule_set_forwarding_free,
974};
975
976int
977route_map_command_status (struct vty *vty, int ret)
978{
979 if (! ret)
980 return CMD_SUCCESS;
981
982 switch (ret)
983 {
984 case RMAP_RULE_MISSING:
hasso049207c2004-08-04 20:02:13 +0000985 vty_out (vty, "Can't find rule.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000986 break;
987 case RMAP_COMPILE_ERROR:
hasso049207c2004-08-04 20:02:13 +0000988 vty_out (vty, "Argument is malformed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000989 break;
990 default:
hasso049207c2004-08-04 20:02:13 +0000991 vty_out (vty, "route-map add set failed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000992 break;
993 }
994 return CMD_WARNING;
995}
996
997/* add "match address" */
998DEFUN (ospf6_routemap_match_address_prefixlist,
999 ospf6_routemap_match_address_prefixlist_cmd,
1000 "match ipv6 address prefix-list WORD",
1001 "Match values\n"
1002 IPV6_STR
1003 "Match address of route\n"
1004 "Match entries of prefix-lists\n"
1005 "IPv6 prefix-list name\n")
1006{
1007 int ret = route_map_add_match ((struct route_map_index *) vty->index,
1008 "ipv6 address prefix-list", argv[0]);
1009 return route_map_command_status (vty, ret);
1010}
1011
1012/* delete "match address" */
1013DEFUN (ospf6_routemap_no_match_address_prefixlist,
1014 ospf6_routemap_no_match_address_prefixlist_cmd,
1015 "no match ipv6 address prefix-list WORD",
1016 NO_STR
1017 "Match values\n"
1018 IPV6_STR
1019 "Match address of route\n"
1020 "Match entries of prefix-lists\n"
1021 "IPv6 prefix-list name\n")
1022{
1023 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1024 "ipv6 address prefix-list", argv[0]);
1025 return route_map_command_status (vty, ret);
1026}
1027
1028/* add "set metric-type" */
1029DEFUN (ospf6_routemap_set_metric_type,
1030 ospf6_routemap_set_metric_type_cmd,
1031 "set metric-type (type-1|type-2)",
1032 "Set value\n"
1033 "Type of metric\n"
1034 "OSPF6 external type 1 metric\n"
1035 "OSPF6 external type 2 metric\n")
1036{
1037 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1038 "metric-type", argv[0]);
1039 return route_map_command_status (vty, ret);
1040}
1041
1042/* delete "set metric-type" */
1043DEFUN (ospf6_routemap_no_set_metric_type,
1044 ospf6_routemap_no_set_metric_type_cmd,
1045 "no set metric-type (type-1|type-2)",
1046 NO_STR
1047 "Set value\n"
1048 "Type of metric\n"
1049 "OSPF6 external type 1 metric\n"
1050 "OSPF6 external type 2 metric\n")
1051{
1052 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1053 "metric-type", argv[0]);
1054 return route_map_command_status (vty, ret);
1055}
1056
1057/* add "set metric" */
1058DEFUN (set_metric,
1059 set_metric_cmd,
1060 "set metric <0-4294967295>",
1061 "Set value\n"
1062 "Metric value\n"
1063 "Metric value\n")
1064{
1065 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1066 "metric", argv[0]);
1067 return route_map_command_status (vty, ret);
1068}
1069
1070/* delete "set metric" */
1071DEFUN (no_set_metric,
1072 no_set_metric_cmd,
1073 "no set metric <0-4294967295>",
1074 NO_STR
1075 "Set value\n"
1076 "Metric\n"
1077 "METRIC value\n")
1078{
1079 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1080 "metric", argv[0]);
1081 return route_map_command_status (vty, ret);
1082}
1083
1084/* add "set forwarding-address" */
1085DEFUN (ospf6_routemap_set_forwarding,
1086 ospf6_routemap_set_forwarding_cmd,
1087 "set forwarding-address X:X::X:X",
1088 "Set value\n"
1089 "Forwarding Address\n"
1090 "IPv6 Address\n")
1091{
1092 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1093 "forwarding-address", argv[0]);
1094 return route_map_command_status (vty, ret);
1095}
1096
1097/* delete "set forwarding-address" */
1098DEFUN (ospf6_routemap_no_set_forwarding,
1099 ospf6_routemap_no_set_forwarding_cmd,
1100 "no set forwarding-address X:X::X:X",
1101 NO_STR
1102 "Set value\n"
1103 "Forwarding Address\n"
1104 "IPv6 Address\n")
1105{
1106 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1107 "forwarding-address", argv[0]);
1108 return route_map_command_status (vty, ret);
1109}
1110
1111void
1112ospf6_routemap_init ()
1113{
1114 route_map_init ();
1115 route_map_init_vty ();
1116 route_map_add_hook (ospf6_asbr_routemap_update);
1117 route_map_delete_hook (ospf6_asbr_routemap_update);
1118
1119 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
1120 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
1121 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
1122 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
1123
1124 /* Match address prefix-list */
1125 install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
1126 install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
1127
1128 /* ASE Metric Type (e.g. Type-1/Type-2) */
1129 install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
1130 install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
1131
1132 /* ASE Metric */
1133 install_element (RMAP_NODE, &set_metric_cmd);
1134 install_element (RMAP_NODE, &no_set_metric_cmd);
1135
1136 /* ASE Metric */
1137 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
1138 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
1139}
1140
1141
1142/* Display functions */
1143int
1144ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
1145{
1146 struct ospf6_as_external_lsa *external;
paul718e3742002-12-13 20:15:29 +00001147 char buf[64];
hasso508e53e2004-05-18 18:57:06 +00001148 struct in6_addr in6, *forwarding;
paul718e3742002-12-13 20:15:29 +00001149
1150 assert (lsa->header);
hasso508e53e2004-05-18 18:57:06 +00001151 external = (struct ospf6_as_external_lsa *)
1152 OSPF6_LSA_HEADER_END (lsa->header);
paul718e3742002-12-13 20:15:29 +00001153
1154 /* bits */
hasso508e53e2004-05-18 18:57:06 +00001155 snprintf (buf, sizeof (buf), "%c%c%c",
1156 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
1157 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
1158 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
paul718e3742002-12-13 20:15:29 +00001159
hasso049207c2004-08-04 20:02:13 +00001160 vty_out (vty, " Bits: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +00001161 vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
hasso049207c2004-08-04 20:02:13 +00001162 VNL);
paul718e3742002-12-13 20:15:29 +00001163
hasso508e53e2004-05-18 18:57:06 +00001164 ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1165 buf, sizeof (buf));
1166 vty_out (vty, " Prefix Options: %s%s", buf,
hasso049207c2004-08-04 20:02:13 +00001167 VNL);
paul718e3742002-12-13 20:15:29 +00001168
1169 vty_out (vty, " Referenced LSType: %d%s",
hasso508e53e2004-05-18 18:57:06 +00001170 ntohs (external->prefix.prefix_refer_lstype),
hasso049207c2004-08-04 20:02:13 +00001171 VNL);
paul718e3742002-12-13 20:15:29 +00001172
hasso508e53e2004-05-18 18:57:06 +00001173 ospf6_prefix_in6_addr (&in6, &external->prefix);
paul718e3742002-12-13 20:15:29 +00001174 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
hasso508e53e2004-05-18 18:57:06 +00001175 vty_out (vty, " Prefix: %s/%d%s", buf,
hasso049207c2004-08-04 20:02:13 +00001176 external->prefix.prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +00001177
1178 /* Forwarding-Address */
1179 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
1180 {
hasso508e53e2004-05-18 18:57:06 +00001181 forwarding = (struct in6_addr *)
1182 ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
1183 OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
1184 inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +00001185 vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
paul718e3742002-12-13 20:15:29 +00001186 }
1187
1188 return 0;
1189}
1190
1191void
hasso508e53e2004-05-18 18:57:06 +00001192ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +00001193{
hasso508e53e2004-05-18 18:57:06 +00001194 struct ospf6_external_info *info = route->route_option;
1195 char prefix[64], id[16], forwarding[64];
1196 u_int32_t tmp_id;
1197
1198 prefix2str (&route->prefix, prefix, sizeof (prefix));
1199 tmp_id = ntohl (info->id);
1200 inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
1201 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
1202 inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
1203 else
1204 snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
1205 route->nexthop[0].ifindex);
1206
1207 vty_out (vty, "%s %-32s %-15s type-%d %5lu %s%s",
1208 ZROUTE_ABNAME (info->type),
1209 prefix, id, route->path.metric_type,
1210 (u_long) (route->path.metric_type == 2 ?
1211 route->path.cost_e2 : route->path.cost),
hasso049207c2004-08-04 20:02:13 +00001212 forwarding, VNL);
paul718e3742002-12-13 20:15:29 +00001213}
1214
hasso508e53e2004-05-18 18:57:06 +00001215DEFUN (show_ipv6_ospf6_redistribute,
1216 show_ipv6_ospf6_redistribute_cmd,
1217 "show ipv6 ospf6 redistribute",
paul718e3742002-12-13 20:15:29 +00001218 SHOW_STR
1219 IP6_STR
paul718e3742002-12-13 20:15:29 +00001220 OSPF6_STR
1221 "redistributing External information\n"
1222 )
1223{
hasso508e53e2004-05-18 18:57:06 +00001224 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +00001225
hasso508e53e2004-05-18 18:57:06 +00001226 ospf6_redistribute_show_config (vty);
1227
1228 for (route = ospf6_route_head (ospf6->external_table); route;
1229 route = ospf6_route_next (route))
1230 ospf6_asbr_external_route_show (vty, route);
1231
paul718e3742002-12-13 20:15:29 +00001232 return CMD_SUCCESS;
1233}
1234
hasso6452df02004-08-15 05:52:07 +00001235struct ospf6_lsa_handler as_external_handler =
hasso508e53e2004-05-18 18:57:06 +00001236{
hasso6452df02004-08-15 05:52:07 +00001237 OSPF6_LSTYPE_AS_EXTERNAL,
1238 "AS-External",
1239 ospf6_as_external_lsa_show
1240};
hasso508e53e2004-05-18 18:57:06 +00001241
paul718e3742002-12-13 20:15:29 +00001242void
1243ospf6_asbr_init ()
1244{
hasso508e53e2004-05-18 18:57:06 +00001245 ospf6_routemap_init ();
paul718e3742002-12-13 20:15:29 +00001246
hasso6452df02004-08-15 05:52:07 +00001247 ospf6_install_lsa_handler (&as_external_handler);
paul718e3742002-12-13 20:15:29 +00001248
hasso508e53e2004-05-18 18:57:06 +00001249 install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
1250 install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
1251
paul718e3742002-12-13 20:15:29 +00001252 install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
1253 install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
1254 install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
1255}
1256
1257
hasso508e53e2004-05-18 18:57:06 +00001258DEFUN (debug_ospf6_asbr,
1259 debug_ospf6_asbr_cmd,
1260 "debug ospf6 asbr",
1261 DEBUG_STR
1262 OSPF6_STR
1263 "Debug OSPFv3 ASBR function\n"
1264 )
1265{
1266 OSPF6_DEBUG_ASBR_ON ();
1267 return CMD_SUCCESS;
1268}
1269
1270DEFUN (no_debug_ospf6_asbr,
1271 no_debug_ospf6_asbr_cmd,
1272 "no debug ospf6 asbr",
1273 NO_STR
1274 DEBUG_STR
1275 OSPF6_STR
1276 "Debug OSPFv3 ASBR function\n"
1277 )
1278{
1279 OSPF6_DEBUG_ASBR_OFF ();
1280 return CMD_SUCCESS;
1281}
1282
1283int
1284config_write_ospf6_debug_asbr (struct vty *vty)
1285{
1286 if (IS_OSPF6_DEBUG_ASBR)
hasso049207c2004-08-04 20:02:13 +00001287 vty_out (vty, "debug ospf6 asbr%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001288 return 0;
1289}
1290
1291void
1292install_element_ospf6_debug_asbr ()
1293{
1294 install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
1295 install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
1296 install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
1297 install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
1298}
1299
1300