blob: 564efb2255f69966b9dcfc87495e32ebea109764 [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];
paul1eb8ef22005-04-07 07:30:20 +0000447 struct listnode *lnode, *lnnode;
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 */
paul1eb8ef22005-04-07 07:30:20 +0000577 for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
578 OSPF6_ROUTER_LSA_SCHEDULE (oa);
hasso508e53e2004-05-18 18:57:06 +0000579}
580
581void
582ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
583{
584 struct ospf6_route *match;
585 struct ospf6_external_info *info = NULL;
586 struct route_node *node;
587 struct ospf6_lsa *lsa;
588 struct prefix prefix_id;
589 char pbuf[64], ibuf[16];
paul1eb8ef22005-04-07 07:30:20 +0000590 struct listnode *lnode, *lnnode;
hasso508e53e2004-05-18 18:57:06 +0000591 struct ospf6_area *oa;
592
593 match = ospf6_route_lookup (prefix, ospf6->external_table);
594 if (match == NULL)
595 {
596 if (IS_OSPF6_DEBUG_ASBR)
597 {
598 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000599 zlog_debug ("No such route %s to withdraw", pbuf);
hasso508e53e2004-05-18 18:57:06 +0000600 }
601 return;
602 }
603
604 info = match->route_option;
605 assert (info);
606
607 if (info->type != type)
608 {
609 if (IS_OSPF6_DEBUG_ASBR)
610 {
611 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000612 zlog_debug ("Original protocol mismatch: %s", pbuf);
hasso508e53e2004-05-18 18:57:06 +0000613 }
614 return;
615 }
616
617 if (IS_OSPF6_DEBUG_ASBR)
618 {
619 prefix2str (prefix, pbuf, sizeof (pbuf));
620 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000621 zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
hasso508e53e2004-05-18 18:57:06 +0000622 }
623
624 lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
625 htonl (info->id), ospf6->router_id, ospf6->lsdb);
626 if (lsa)
hasso6452df02004-08-15 05:52:07 +0000627 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000628
629 /* remove binding in external_id_table */
630 prefix_id.family = AF_INET;
631 prefix_id.prefixlen = 32;
632 prefix_id.u.prefix4.s_addr = htonl (info->id);
633 node = route_node_lookup (ospf6->external_id_table, &prefix_id);
634 assert (node);
635 node->info = NULL;
636 route_unlock_node (node);
637
638 ospf6_route_remove (match, ospf6->external_table);
639 XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
640
641 /* Router-Bit (ASBR Flag) may have to be updated */
paul1eb8ef22005-04-07 07:30:20 +0000642 for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
643 OSPF6_ROUTER_LSA_SCHEDULE (oa);
paul718e3742002-12-13 20:15:29 +0000644}
645
646DEFUN (ospf6_redistribute,
647 ospf6_redistribute_cmd,
648 "redistribute (static|kernel|connected|ripng|bgp)",
649 "Redistribute\n"
650 "Static route\n"
651 "Kernel route\n"
652 "Connected route\n"
653 "RIPng route\n"
654 "BGP route\n"
655 )
656{
657 int type = 0;
658
659 if (strncmp (argv[0], "sta", 3) == 0)
660 type = ZEBRA_ROUTE_STATIC;
661 else if (strncmp (argv[0], "ker", 3) == 0)
662 type = ZEBRA_ROUTE_KERNEL;
663 else if (strncmp (argv[0], "con", 3) == 0)
664 type = ZEBRA_ROUTE_CONNECT;
665 else if (strncmp (argv[0], "rip", 3) == 0)
666 type = ZEBRA_ROUTE_RIPNG;
667 else if (strncmp (argv[0], "bgp", 3) == 0)
668 type = ZEBRA_ROUTE_BGP;
669
hasso508e53e2004-05-18 18:57:06 +0000670 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000671 ospf6_asbr_routemap_unset (type);
hasso508e53e2004-05-18 18:57:06 +0000672 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000673 return CMD_SUCCESS;
674}
675
676DEFUN (ospf6_redistribute_routemap,
677 ospf6_redistribute_routemap_cmd,
678 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
679 "Redistribute\n"
680 "Static routes\n"
681 "Kernel route\n"
682 "Connected route\n"
683 "RIPng route\n"
684 "BGP route\n"
685 "Route map reference\n"
686 "Route map name\n"
687 )
688{
689 int type = 0;
690
691 if (strncmp (argv[0], "sta", 3) == 0)
692 type = ZEBRA_ROUTE_STATIC;
693 else if (strncmp (argv[0], "ker", 3) == 0)
694 type = ZEBRA_ROUTE_KERNEL;
695 else if (strncmp (argv[0], "con", 3) == 0)
696 type = ZEBRA_ROUTE_CONNECT;
697 else if (strncmp (argv[0], "rip", 3) == 0)
698 type = ZEBRA_ROUTE_RIPNG;
699 else if (strncmp (argv[0], "bgp", 3) == 0)
700 type = ZEBRA_ROUTE_BGP;
701
hasso508e53e2004-05-18 18:57:06 +0000702 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000703 ospf6_asbr_routemap_set (type, argv[1]);
hasso508e53e2004-05-18 18:57:06 +0000704 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000705 return CMD_SUCCESS;
706}
707
708DEFUN (no_ospf6_redistribute,
709 no_ospf6_redistribute_cmd,
710 "no redistribute (static|kernel|connected|ripng|bgp)",
711 NO_STR
712 "Redistribute\n"
713 "Static route\n"
714 "Kernel route\n"
715 "Connected route\n"
716 "RIPng route\n"
717 "BGP route\n"
718 )
719{
720 int type = 0;
paul718e3742002-12-13 20:15:29 +0000721
722 if (strncmp (argv[0], "sta", 3) == 0)
723 type = ZEBRA_ROUTE_STATIC;
724 else if (strncmp (argv[0], "ker", 3) == 0)
725 type = ZEBRA_ROUTE_KERNEL;
726 else if (strncmp (argv[0], "con", 3) == 0)
727 type = ZEBRA_ROUTE_CONNECT;
728 else if (strncmp (argv[0], "rip", 3) == 0)
729 type = ZEBRA_ROUTE_RIPNG;
730 else if (strncmp (argv[0], "bgp", 3) == 0)
731 type = ZEBRA_ROUTE_BGP;
732
hasso508e53e2004-05-18 18:57:06 +0000733 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000734 ospf6_asbr_routemap_unset (type);
735
paul718e3742002-12-13 20:15:29 +0000736 return CMD_SUCCESS;
737}
738
paul718e3742002-12-13 20:15:29 +0000739int
740ospf6_redistribute_config_write (struct vty *vty)
741{
hasso508e53e2004-05-18 18:57:06 +0000742 int type;
paul718e3742002-12-13 20:15:29 +0000743
hasso508e53e2004-05-18 18:57:06 +0000744 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000745 {
hasso508e53e2004-05-18 18:57:06 +0000746 if (type == ZEBRA_ROUTE_OSPF6)
747 continue;
748 if (! ospf6_zebra_is_redistribute (type))
paul718e3742002-12-13 20:15:29 +0000749 continue;
750
hasso508e53e2004-05-18 18:57:06 +0000751 if (ospf6->rmap[type].name)
paul718e3742002-12-13 20:15:29 +0000752 vty_out (vty, " redistribute %s route-map %s%s",
hasso049207c2004-08-04 20:02:13 +0000753 ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
paul718e3742002-12-13 20:15:29 +0000754 else
755 vty_out (vty, " redistribute %s%s",
hasso049207c2004-08-04 20:02:13 +0000756 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000757 }
758
759 return 0;
760}
761
762void
763ospf6_redistribute_show_config (struct vty *vty)
764{
hasso508e53e2004-05-18 18:57:06 +0000765 int type;
766 int nroute[ZEBRA_ROUTE_MAX];
767 int total;
768 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000769 struct ospf6_external_info *info;
paul718e3742002-12-13 20:15:29 +0000770
hasso508e53e2004-05-18 18:57:06 +0000771 total = 0;
772 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
773 nroute[type] = 0;
774 for (route = ospf6_route_head (ospf6->external_table); route;
775 route = ospf6_route_next (route))
paul718e3742002-12-13 20:15:29 +0000776 {
hasso508e53e2004-05-18 18:57:06 +0000777 info = route->route_option;
778 nroute[info->type]++;
779 total++;
paul718e3742002-12-13 20:15:29 +0000780 }
781
hasso049207c2004-08-04 20:02:13 +0000782 vty_out (vty, "Redistributing External Routes from:%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000783 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000784 {
hasso508e53e2004-05-18 18:57:06 +0000785 if (type == ZEBRA_ROUTE_OSPF6)
786 continue;
787 if (! ospf6_zebra_is_redistribute (type))
hassoe26bbeb2003-05-25 21:39:29 +0000788 continue;
789
hasso508e53e2004-05-18 18:57:06 +0000790 if (ospf6->rmap[type].name)
791 vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
792 ZROUTE_NAME (type), ospf6->rmap[type].name,
793 (ospf6->rmap[type].map ? "" : " (not found !)"),
hasso049207c2004-08-04 20:02:13 +0000794 VNL);
paul718e3742002-12-13 20:15:29 +0000795 else
hasso508e53e2004-05-18 18:57:06 +0000796 vty_out (vty, " %d: %s%s", nroute[type],
hasso049207c2004-08-04 20:02:13 +0000797 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000798 }
hasso049207c2004-08-04 20:02:13 +0000799 vty_out (vty, "Total %d routes%s", total, VNL);
hasso508e53e2004-05-18 18:57:06 +0000800}
paul718e3742002-12-13 20:15:29 +0000801
paul718e3742002-12-13 20:15:29 +0000802
hasso508e53e2004-05-18 18:57:06 +0000803
804/* Routemap Functions */
805route_map_result_t
806ospf6_routemap_rule_match_address_prefixlist (void *rule,
807 struct prefix *prefix,
808 route_map_object_t type,
809 void *object)
810{
811 struct prefix_list *plist;
paul718e3742002-12-13 20:15:29 +0000812
hasso508e53e2004-05-18 18:57:06 +0000813 if (type != RMAP_OSPF6)
814 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000815
hasso508e53e2004-05-18 18:57:06 +0000816 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
817 if (plist == NULL)
818 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000819
hasso508e53e2004-05-18 18:57:06 +0000820 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
821 RMAP_NOMATCH : RMAP_MATCH);
822}
paul718e3742002-12-13 20:15:29 +0000823
hasso508e53e2004-05-18 18:57:06 +0000824void *
paul0c083ee2004-10-10 12:54:58 +0000825ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000826{
827 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000828}
829
830void
hasso508e53e2004-05-18 18:57:06 +0000831ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000832{
hasso508e53e2004-05-18 18:57:06 +0000833 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
834}
paul718e3742002-12-13 20:15:29 +0000835
hasso508e53e2004-05-18 18:57:06 +0000836struct route_map_rule_cmd
837ospf6_routemap_rule_match_address_prefixlist_cmd =
838{
839 "ipv6 address prefix-list",
840 ospf6_routemap_rule_match_address_prefixlist,
841 ospf6_routemap_rule_match_address_prefixlist_compile,
842 ospf6_routemap_rule_match_address_prefixlist_free,
843};
hassoe26bbeb2003-05-25 21:39:29 +0000844
hasso508e53e2004-05-18 18:57:06 +0000845route_map_result_t
846ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
847 route_map_object_t type, void *object)
848{
849 char *metric_type = rule;
850 struct ospf6_route *route = object;
hassoe26bbeb2003-05-25 21:39:29 +0000851
hasso508e53e2004-05-18 18:57:06 +0000852 if (type != RMAP_OSPF6)
853 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000854
hasso508e53e2004-05-18 18:57:06 +0000855 if (strcmp (metric_type, "type-2") == 0)
856 route->path.metric_type = 2;
paul718e3742002-12-13 20:15:29 +0000857 else
hasso508e53e2004-05-18 18:57:06 +0000858 route->path.metric_type = 1;
paul718e3742002-12-13 20:15:29 +0000859
hasso508e53e2004-05-18 18:57:06 +0000860 return RMAP_OKAY;
861}
paul718e3742002-12-13 20:15:29 +0000862
hasso508e53e2004-05-18 18:57:06 +0000863void *
paul0c083ee2004-10-10 12:54:58 +0000864ospf6_routemap_rule_set_metric_type_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000865{
866 if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
867 return NULL;
868 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000869}
870
871void
hasso508e53e2004-05-18 18:57:06 +0000872ospf6_routemap_rule_set_metric_type_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000873{
hasso508e53e2004-05-18 18:57:06 +0000874 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
875}
paul718e3742002-12-13 20:15:29 +0000876
hasso508e53e2004-05-18 18:57:06 +0000877struct route_map_rule_cmd
878ospf6_routemap_rule_set_metric_type_cmd =
879{
880 "metric-type",
881 ospf6_routemap_rule_set_metric_type,
882 ospf6_routemap_rule_set_metric_type_compile,
883 ospf6_routemap_rule_set_metric_type_free,
884};
paul718e3742002-12-13 20:15:29 +0000885
hasso508e53e2004-05-18 18:57:06 +0000886route_map_result_t
887ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
888 route_map_object_t type, void *object)
889{
890 char *metric = rule;
891 struct ospf6_route *route = object;
paul718e3742002-12-13 20:15:29 +0000892
hasso508e53e2004-05-18 18:57:06 +0000893 if (type != RMAP_OSPF6)
894 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000895
hasso508e53e2004-05-18 18:57:06 +0000896 route->path.cost = atoi (metric);
897 return RMAP_OKAY;
898}
paul718e3742002-12-13 20:15:29 +0000899
hasso508e53e2004-05-18 18:57:06 +0000900void *
paul0c083ee2004-10-10 12:54:58 +0000901ospf6_routemap_rule_set_metric_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000902{
903 u_int32_t metric;
904 char *endp;
905 metric = strtoul (arg, &endp, 0);
906 if (metric > LS_INFINITY || *endp != '\0')
907 return NULL;
908 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000909}
910
911void
hasso508e53e2004-05-18 18:57:06 +0000912ospf6_routemap_rule_set_metric_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000913{
hasso508e53e2004-05-18 18:57:06 +0000914 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
915}
916
917struct route_map_rule_cmd
918ospf6_routemap_rule_set_metric_cmd =
919{
920 "metric",
921 ospf6_routemap_rule_set_metric,
922 ospf6_routemap_rule_set_metric_compile,
923 ospf6_routemap_rule_set_metric_free,
924};
925
926route_map_result_t
927ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
928 route_map_object_t type, void *object)
929{
930 char *forwarding = rule;
931 struct ospf6_route *route = object;
932 struct ospf6_external_info *info = route->route_option;
933
934 if (type != RMAP_OSPF6)
935 return RMAP_OKAY;
936
937 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
938 {
939 memset (&info->forwarding, 0, sizeof (struct in6_addr));
940 return RMAP_ERROR;
941 }
942
943 return RMAP_OKAY;
944}
945
946void *
paul0c083ee2004-10-10 12:54:58 +0000947ospf6_routemap_rule_set_forwarding_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000948{
949 struct in6_addr a;
950 if (inet_pton (AF_INET6, arg, &a) != 1)
951 return NULL;
952 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
953}
954
955void
956ospf6_routemap_rule_set_forwarding_free (void *rule)
957{
958 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
959}
960
961struct route_map_rule_cmd
962ospf6_routemap_rule_set_forwarding_cmd =
963{
964 "forwarding-address",
965 ospf6_routemap_rule_set_forwarding,
966 ospf6_routemap_rule_set_forwarding_compile,
967 ospf6_routemap_rule_set_forwarding_free,
968};
969
970int
971route_map_command_status (struct vty *vty, int ret)
972{
973 if (! ret)
974 return CMD_SUCCESS;
975
976 switch (ret)
977 {
978 case RMAP_RULE_MISSING:
hasso049207c2004-08-04 20:02:13 +0000979 vty_out (vty, "Can't find rule.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000980 break;
981 case RMAP_COMPILE_ERROR:
hasso049207c2004-08-04 20:02:13 +0000982 vty_out (vty, "Argument is malformed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000983 break;
984 default:
hasso049207c2004-08-04 20:02:13 +0000985 vty_out (vty, "route-map add set failed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000986 break;
987 }
988 return CMD_WARNING;
989}
990
991/* add "match address" */
992DEFUN (ospf6_routemap_match_address_prefixlist,
993 ospf6_routemap_match_address_prefixlist_cmd,
994 "match ipv6 address prefix-list WORD",
995 "Match values\n"
996 IPV6_STR
997 "Match address of route\n"
998 "Match entries of prefix-lists\n"
999 "IPv6 prefix-list name\n")
1000{
1001 int ret = route_map_add_match ((struct route_map_index *) vty->index,
1002 "ipv6 address prefix-list", argv[0]);
1003 return route_map_command_status (vty, ret);
1004}
1005
1006/* delete "match address" */
1007DEFUN (ospf6_routemap_no_match_address_prefixlist,
1008 ospf6_routemap_no_match_address_prefixlist_cmd,
1009 "no match ipv6 address prefix-list WORD",
1010 NO_STR
1011 "Match values\n"
1012 IPV6_STR
1013 "Match address of route\n"
1014 "Match entries of prefix-lists\n"
1015 "IPv6 prefix-list name\n")
1016{
1017 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1018 "ipv6 address prefix-list", argv[0]);
1019 return route_map_command_status (vty, ret);
1020}
1021
1022/* add "set metric-type" */
1023DEFUN (ospf6_routemap_set_metric_type,
1024 ospf6_routemap_set_metric_type_cmd,
1025 "set metric-type (type-1|type-2)",
1026 "Set value\n"
1027 "Type of metric\n"
1028 "OSPF6 external type 1 metric\n"
1029 "OSPF6 external type 2 metric\n")
1030{
1031 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1032 "metric-type", argv[0]);
1033 return route_map_command_status (vty, ret);
1034}
1035
1036/* delete "set metric-type" */
1037DEFUN (ospf6_routemap_no_set_metric_type,
1038 ospf6_routemap_no_set_metric_type_cmd,
1039 "no set metric-type (type-1|type-2)",
1040 NO_STR
1041 "Set value\n"
1042 "Type of metric\n"
1043 "OSPF6 external type 1 metric\n"
1044 "OSPF6 external type 2 metric\n")
1045{
1046 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1047 "metric-type", argv[0]);
1048 return route_map_command_status (vty, ret);
1049}
1050
1051/* add "set metric" */
1052DEFUN (set_metric,
1053 set_metric_cmd,
1054 "set metric <0-4294967295>",
1055 "Set value\n"
1056 "Metric value\n"
1057 "Metric value\n")
1058{
1059 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1060 "metric", argv[0]);
1061 return route_map_command_status (vty, ret);
1062}
1063
1064/* delete "set metric" */
1065DEFUN (no_set_metric,
1066 no_set_metric_cmd,
1067 "no set metric <0-4294967295>",
1068 NO_STR
1069 "Set value\n"
1070 "Metric\n"
1071 "METRIC value\n")
1072{
1073 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1074 "metric", argv[0]);
1075 return route_map_command_status (vty, ret);
1076}
1077
1078/* add "set forwarding-address" */
1079DEFUN (ospf6_routemap_set_forwarding,
1080 ospf6_routemap_set_forwarding_cmd,
1081 "set forwarding-address X:X::X:X",
1082 "Set value\n"
1083 "Forwarding Address\n"
1084 "IPv6 Address\n")
1085{
1086 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1087 "forwarding-address", argv[0]);
1088 return route_map_command_status (vty, ret);
1089}
1090
1091/* delete "set forwarding-address" */
1092DEFUN (ospf6_routemap_no_set_forwarding,
1093 ospf6_routemap_no_set_forwarding_cmd,
1094 "no set forwarding-address X:X::X:X",
1095 NO_STR
1096 "Set value\n"
1097 "Forwarding Address\n"
1098 "IPv6 Address\n")
1099{
1100 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1101 "forwarding-address", argv[0]);
1102 return route_map_command_status (vty, ret);
1103}
1104
1105void
1106ospf6_routemap_init ()
1107{
1108 route_map_init ();
1109 route_map_init_vty ();
1110 route_map_add_hook (ospf6_asbr_routemap_update);
1111 route_map_delete_hook (ospf6_asbr_routemap_update);
1112
1113 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
1114 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
1115 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
1116 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
1117
1118 /* Match address prefix-list */
1119 install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
1120 install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
1121
1122 /* ASE Metric Type (e.g. Type-1/Type-2) */
1123 install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
1124 install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
1125
1126 /* ASE Metric */
1127 install_element (RMAP_NODE, &set_metric_cmd);
1128 install_element (RMAP_NODE, &no_set_metric_cmd);
1129
1130 /* ASE Metric */
1131 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
1132 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
1133}
1134
1135
1136/* Display functions */
1137int
1138ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
1139{
1140 struct ospf6_as_external_lsa *external;
paul718e3742002-12-13 20:15:29 +00001141 char buf[64];
hasso508e53e2004-05-18 18:57:06 +00001142 struct in6_addr in6, *forwarding;
paul718e3742002-12-13 20:15:29 +00001143
1144 assert (lsa->header);
hasso508e53e2004-05-18 18:57:06 +00001145 external = (struct ospf6_as_external_lsa *)
1146 OSPF6_LSA_HEADER_END (lsa->header);
paul718e3742002-12-13 20:15:29 +00001147
1148 /* bits */
hasso508e53e2004-05-18 18:57:06 +00001149 snprintf (buf, sizeof (buf), "%c%c%c",
1150 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
1151 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
1152 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
paul718e3742002-12-13 20:15:29 +00001153
hasso049207c2004-08-04 20:02:13 +00001154 vty_out (vty, " Bits: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +00001155 vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
hasso049207c2004-08-04 20:02:13 +00001156 VNL);
paul718e3742002-12-13 20:15:29 +00001157
hasso508e53e2004-05-18 18:57:06 +00001158 ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1159 buf, sizeof (buf));
1160 vty_out (vty, " Prefix Options: %s%s", buf,
hasso049207c2004-08-04 20:02:13 +00001161 VNL);
paul718e3742002-12-13 20:15:29 +00001162
1163 vty_out (vty, " Referenced LSType: %d%s",
hasso508e53e2004-05-18 18:57:06 +00001164 ntohs (external->prefix.prefix_refer_lstype),
hasso049207c2004-08-04 20:02:13 +00001165 VNL);
paul718e3742002-12-13 20:15:29 +00001166
hasso508e53e2004-05-18 18:57:06 +00001167 ospf6_prefix_in6_addr (&in6, &external->prefix);
paul718e3742002-12-13 20:15:29 +00001168 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
hasso508e53e2004-05-18 18:57:06 +00001169 vty_out (vty, " Prefix: %s/%d%s", buf,
hasso049207c2004-08-04 20:02:13 +00001170 external->prefix.prefix_length, VNL);
paul718e3742002-12-13 20:15:29 +00001171
1172 /* Forwarding-Address */
1173 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
1174 {
hasso508e53e2004-05-18 18:57:06 +00001175 forwarding = (struct in6_addr *)
1176 ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
1177 OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
1178 inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
hasso049207c2004-08-04 20:02:13 +00001179 vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
paul718e3742002-12-13 20:15:29 +00001180 }
1181
1182 return 0;
1183}
1184
1185void
hasso508e53e2004-05-18 18:57:06 +00001186ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +00001187{
hasso508e53e2004-05-18 18:57:06 +00001188 struct ospf6_external_info *info = route->route_option;
1189 char prefix[64], id[16], forwarding[64];
1190 u_int32_t tmp_id;
1191
1192 prefix2str (&route->prefix, prefix, sizeof (prefix));
1193 tmp_id = ntohl (info->id);
1194 inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
1195 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
1196 inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
1197 else
1198 snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
1199 route->nexthop[0].ifindex);
1200
1201 vty_out (vty, "%s %-32s %-15s type-%d %5lu %s%s",
1202 ZROUTE_ABNAME (info->type),
1203 prefix, id, route->path.metric_type,
1204 (u_long) (route->path.metric_type == 2 ?
1205 route->path.cost_e2 : route->path.cost),
hasso049207c2004-08-04 20:02:13 +00001206 forwarding, VNL);
paul718e3742002-12-13 20:15:29 +00001207}
1208
hasso508e53e2004-05-18 18:57:06 +00001209DEFUN (show_ipv6_ospf6_redistribute,
1210 show_ipv6_ospf6_redistribute_cmd,
1211 "show ipv6 ospf6 redistribute",
paul718e3742002-12-13 20:15:29 +00001212 SHOW_STR
1213 IP6_STR
paul718e3742002-12-13 20:15:29 +00001214 OSPF6_STR
1215 "redistributing External information\n"
1216 )
1217{
hasso508e53e2004-05-18 18:57:06 +00001218 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +00001219
hasso508e53e2004-05-18 18:57:06 +00001220 ospf6_redistribute_show_config (vty);
1221
1222 for (route = ospf6_route_head (ospf6->external_table); route;
1223 route = ospf6_route_next (route))
1224 ospf6_asbr_external_route_show (vty, route);
1225
paul718e3742002-12-13 20:15:29 +00001226 return CMD_SUCCESS;
1227}
1228
hasso6452df02004-08-15 05:52:07 +00001229struct ospf6_lsa_handler as_external_handler =
hasso508e53e2004-05-18 18:57:06 +00001230{
hasso6452df02004-08-15 05:52:07 +00001231 OSPF6_LSTYPE_AS_EXTERNAL,
1232 "AS-External",
1233 ospf6_as_external_lsa_show
1234};
hasso508e53e2004-05-18 18:57:06 +00001235
paul718e3742002-12-13 20:15:29 +00001236void
1237ospf6_asbr_init ()
1238{
hasso508e53e2004-05-18 18:57:06 +00001239 ospf6_routemap_init ();
paul718e3742002-12-13 20:15:29 +00001240
hasso6452df02004-08-15 05:52:07 +00001241 ospf6_install_lsa_handler (&as_external_handler);
paul718e3742002-12-13 20:15:29 +00001242
hasso508e53e2004-05-18 18:57:06 +00001243 install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
1244 install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
1245
paul718e3742002-12-13 20:15:29 +00001246 install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
1247 install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
1248 install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
1249}
1250
1251
hasso508e53e2004-05-18 18:57:06 +00001252DEFUN (debug_ospf6_asbr,
1253 debug_ospf6_asbr_cmd,
1254 "debug ospf6 asbr",
1255 DEBUG_STR
1256 OSPF6_STR
1257 "Debug OSPFv3 ASBR function\n"
1258 )
1259{
1260 OSPF6_DEBUG_ASBR_ON ();
1261 return CMD_SUCCESS;
1262}
1263
1264DEFUN (no_debug_ospf6_asbr,
1265 no_debug_ospf6_asbr_cmd,
1266 "no debug ospf6 asbr",
1267 NO_STR
1268 DEBUG_STR
1269 OSPF6_STR
1270 "Debug OSPFv3 ASBR function\n"
1271 )
1272{
1273 OSPF6_DEBUG_ASBR_OFF ();
1274 return CMD_SUCCESS;
1275}
1276
1277int
1278config_write_ospf6_debug_asbr (struct vty *vty)
1279{
1280 if (IS_OSPF6_DEBUG_ASBR)
hasso049207c2004-08-04 20:02:13 +00001281 vty_out (vty, "debug ospf6 asbr%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001282 return 0;
1283}
1284
1285void
1286install_element_ospf6_debug_asbr ()
1287{
1288 install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
1289 install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
1290 install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
1291 install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
1292}
1293
1294