blob: a442506c7ae99628a253264fab7dbaac833d21d1 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
hasso508e53e2004-05-18 18:57:06 +00002 * Copyright (C) 2003 Yasuhiro Ohara
paul718e3742002-12-13 20:15:29 +00003 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "log.h"
25#include "memory.h"
26#include "prefix.h"
27#include "command.h"
28#include "vty.h"
29#include "routemap.h"
30#include "table.h"
31#include "plist.h"
32#include "thread.h"
hasso508e53e2004-05-18 18:57:06 +000033#include "linklist.h"
paul718e3742002-12-13 20:15:29 +000034
paul718e3742002-12-13 20:15:29 +000035#include "ospf6_proto.h"
hasso508e53e2004-05-18 18:57:06 +000036#include "ospf6_lsa.h"
37#include "ospf6_lsdb.h"
38#include "ospf6_route.h"
39#include "ospf6_zebra.h"
hasso6452df02004-08-15 05:52:07 +000040#include "ospf6_message.h"
41
hasso508e53e2004-05-18 18:57:06 +000042#include "ospf6_top.h"
43#include "ospf6_area.h"
hasso6452df02004-08-15 05:52:07 +000044#include "ospf6_interface.h"
45#include "ospf6_neighbor.h"
hasso508e53e2004-05-18 18:57:06 +000046#include "ospf6_asbr.h"
47#include "ospf6_intra.h"
hasso6452df02004-08-15 05:52:07 +000048#include "ospf6_flood.h"
hasso049207c2004-08-04 20:02:13 +000049#include "ospf6d.h"
paul718e3742002-12-13 20:15:29 +000050
hasso508e53e2004-05-18 18:57:06 +000051unsigned char conf_debug_ospf6_asbr = 0;
paul718e3742002-12-13 20:15:29 +000052
ajsf52d13c2005-10-01 17:38:06 +000053#define ZROUTE_NAME(x) zebra_route_string(x)
hasso508e53e2004-05-18 18:57:06 +000054
55/* AS External LSA origination */
Paul Jakma6ac29a52008-08-15 13:45:30 +010056static void
hasso6452df02004-08-15 05:52:07 +000057ospf6_as_external_lsa_originate (struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +000058{
hasso508e53e2004-05-18 18:57:06 +000059 char buffer[OSPF6_MAX_LSASIZE];
60 struct ospf6_lsa_header *lsa_header;
Paul Jakma7aa9dce2014-09-19 14:42:23 +010061 struct ospf6_lsa *lsa;
Paul Jakma0b26f812006-05-15 10:47:53 +000062 struct ospf6_external_info *info = route->route_option;
paul718e3742002-12-13 20:15:29 +000063
hasso508e53e2004-05-18 18:57:06 +000064 struct ospf6_as_external_lsa *as_external_lsa;
65 char buf[64];
66 caddr_t p;
paul718e3742002-12-13 20:15:29 +000067
hasso1e058382004-09-01 21:36:14 +000068 if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +000069 {
70 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +000071 zlog_debug ("Originate AS-External-LSA for %s", buf);
hasso508e53e2004-05-18 18:57:06 +000072 }
73
74 /* prepare buffer */
75 memset (buffer, 0, sizeof (buffer));
76 lsa_header = (struct ospf6_lsa_header *) buffer;
77 as_external_lsa = (struct ospf6_as_external_lsa *)
78 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
79 p = (caddr_t)
80 ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));
81
82 /* Fill AS-External-LSA */
83 /* Metric type */
84 if (route->path.metric_type == 2)
85 SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
86 else
87 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
88
89 /* forwarding address */
Paul Jakma0b26f812006-05-15 10:47:53 +000090 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
hasso508e53e2004-05-18 18:57:06 +000091 SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
92 else
93 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
94
95 /* external route tag */
Christian Franke7ae2b602016-10-01 06:41:40 +020096 if (info->tag)
97 SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
98 else
99 UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
hasso508e53e2004-05-18 18:57:06 +0000100
101 /* Set metric */
102 OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
103
104 /* prefixlen */
105 as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
106
107 /* PrefixOptions */
108 as_external_lsa->prefix.prefix_options = route->path.prefix_options;
109
110 /* don't use refer LS-type */
111 as_external_lsa->prefix.prefix_refer_lstype = htons (0);
112
113 /* set Prefix */
114 memcpy (p, &route->prefix.u.prefix6,
115 OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
116 ospf6_prefix_apply_mask (&as_external_lsa->prefix);
117 p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
118
119 /* Forwarding address */
120 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
121 {
Paul Jakma0b26f812006-05-15 10:47:53 +0000122 memcpy (p, &info->forwarding, sizeof (struct in6_addr));
hasso508e53e2004-05-18 18:57:06 +0000123 p += sizeof (struct in6_addr);
124 }
125
126 /* External Route Tag */
127 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
128 {
Christian Franke7ae2b602016-10-01 06:41:40 +0200129 route_tag_t network_order = htonl(info->tag);
130
131 memcpy (p, &network_order, sizeof(network_order));
132 p += sizeof(network_order);
hasso508e53e2004-05-18 18:57:06 +0000133 }
134
135 /* Fill LSA Header */
136 lsa_header->age = 0;
137 lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
hasso6452df02004-08-15 05:52:07 +0000138 lsa_header->id = route->path.origin.id;
hasso508e53e2004-05-18 18:57:06 +0000139 lsa_header->adv_router = ospf6->router_id;
140 lsa_header->seqnum =
hasso049207c2004-08-04 20:02:13 +0000141 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
142 lsa_header->adv_router, ospf6->lsdb);
hasso508e53e2004-05-18 18:57:06 +0000143 lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
144
145 /* LSA checksum */
146 ospf6_lsa_checksum (lsa_header);
147
148 /* create LSA */
149 lsa = ospf6_lsa_create (lsa_header);
hasso508e53e2004-05-18 18:57:06 +0000150
151 /* Originate */
hasso6452df02004-08-15 05:52:07 +0000152 ospf6_lsa_originate_process (lsa, ospf6);
hasso508e53e2004-05-18 18:57:06 +0000153}
154
Christian Franke7ae2b602016-10-01 06:41:40 +0200155static route_tag_t
156ospf6_as_external_lsa_get_tag (struct ospf6_lsa *lsa)
157{
158 struct ospf6_as_external_lsa *external;
159 ptrdiff_t tag_offset;
160 route_tag_t network_order;
161
162 if (!lsa)
163 return 0;
164
165 external = (struct ospf6_as_external_lsa *)
166 OSPF6_LSA_HEADER_END (lsa->header);
167
168 if (!CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T))
169 return 0;
170
171 tag_offset = sizeof(*external) + OSPF6_PREFIX_SPACE(external->prefix.prefix_length);
172 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
173 tag_offset += sizeof(struct in6_addr);
174
175 memcpy(&network_order, (caddr_t)external + tag_offset, sizeof(network_order));
176 return ntohl(network_order);
177}
David Lamparter6b0655a2014-06-04 06:53:35 +0200178
hasso508e53e2004-05-18 18:57:06 +0000179void
180ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
181{
182 struct ospf6_as_external_lsa *external;
183 struct prefix asbr_id;
184 struct ospf6_route *asbr_entry, *route;
185 char buf[64];
186 int i;
187
188 external = (struct ospf6_as_external_lsa *)
189 OSPF6_LSA_HEADER_END (lsa->header);
190
hasso1e058382004-09-01 21:36:14 +0000191 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000192 zlog_debug ("Calculate AS-External route for %s", lsa->name);
hasso508e53e2004-05-18 18:57:06 +0000193
194 if (lsa->header->adv_router == ospf6->router_id)
195 {
hasso1e058382004-09-01 21:36:14 +0000196 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000197 zlog_debug ("Ignore self-originated AS-External-LSA");
hasso508e53e2004-05-18 18:57:06 +0000198 return;
199 }
200
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700201 if (OSPF6_ASBR_METRIC (external) == OSPF_LS_INFINITY)
hasso508e53e2004-05-18 18:57:06 +0000202 {
hasso1e058382004-09-01 21:36:14 +0000203 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000204 zlog_debug ("Ignore LSA with LSInfinity Metric");
hasso508e53e2004-05-18 18:57:06 +0000205 return;
206 }
207
Dinesh Dutt01879112013-08-25 03:03:31 +0000208 if (CHECK_FLAG(external->prefix.prefix_options, OSPF6_PREFIX_OPTION_NU))
209 {
210 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
211 zlog_debug ("Ignore LSA with NU bit set Metric");
212 return;
213 }
214
hassoccb59b12004-08-25 09:10:37 +0000215 ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);
hasso6452df02004-08-15 05:52:07 +0000216 asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
hasso63069ad2004-09-02 13:01:01 +0000217 if (asbr_entry == NULL ||
218 ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))
hasso508e53e2004-05-18 18:57:06 +0000219 {
hasso1e058382004-09-01 21:36:14 +0000220 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000221 {
222 prefix2str (&asbr_id, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000223 zlog_debug ("ASBR entry not found: %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000224 }
225 return;
226 }
227
228 route = ospf6_route_create ();
229 route->type = OSPF6_DEST_TYPE_NETWORK;
230 route->prefix.family = AF_INET6;
231 route->prefix.prefixlen = external->prefix.prefix_length;
232 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
233
234 route->path.area_id = asbr_entry->path.area_id;
235 route->path.origin.type = lsa->header->type;
236 route->path.origin.id = lsa->header->id;
237 route->path.origin.adv_router = lsa->header->adv_router;
238
239 route->path.prefix_options = external->prefix.prefix_options;
240 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
241 {
242 route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
243 route->path.metric_type = 2;
244 route->path.cost = asbr_entry->path.cost;
245 route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
246 }
247 else
248 {
249 route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
250 route->path.metric_type = 1;
251 route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
252 route->path.cost_e2 = 0;
253 }
254
Christian Franke7ae2b602016-10-01 06:41:40 +0200255 route->path.tag = ospf6_as_external_lsa_get_tag (lsa);
256
hasso508e53e2004-05-18 18:57:06 +0000257 for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
258 ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
259
hasso1e058382004-09-01 21:36:14 +0000260 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000261 {
262 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000263 zlog_debug ("AS-External route add: %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000264 }
265
266 ospf6_route_add (route, ospf6->route_table);
267}
268
269void
270ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
271{
272 struct ospf6_as_external_lsa *external;
273 struct prefix prefix;
Vipin Kumar8c075ef2015-05-19 18:03:53 -0700274 struct ospf6_route *route, *nroute;
hasso508e53e2004-05-18 18:57:06 +0000275 char buf[64];
276
277 external = (struct ospf6_as_external_lsa *)
278 OSPF6_LSA_HEADER_END (lsa->header);
279
hasso1e058382004-09-01 21:36:14 +0000280 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000281 zlog_debug ("Withdraw AS-External route for %s", lsa->name);
hasso508e53e2004-05-18 18:57:06 +0000282
283 if (lsa->header->adv_router == ospf6->router_id)
284 {
hasso1e058382004-09-01 21:36:14 +0000285 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hassoc6487d62004-12-24 06:00:11 +0000286 zlog_debug ("Ignore self-originated AS-External-LSA");
hasso508e53e2004-05-18 18:57:06 +0000287 return;
288 }
289
290 memset (&prefix, 0, sizeof (struct prefix));
291 prefix.family = AF_INET6;
292 prefix.prefixlen = external->prefix.prefix_length;
293 ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
294
295 route = ospf6_route_lookup (&prefix, ospf6->route_table);
296 if (route == NULL)
297 {
hasso1e058382004-09-01 21:36:14 +0000298 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000299 {
300 prefix2str (&prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000301 zlog_debug ("AS-External route %s not found", buf);
hasso508e53e2004-05-18 18:57:06 +0000302 }
303 return;
304 }
305
306 for (ospf6_route_lock (route);
307 route && ospf6_route_is_prefix (&prefix, route);
Vipin Kumar8c075ef2015-05-19 18:03:53 -0700308 route = nroute)
hasso508e53e2004-05-18 18:57:06 +0000309 {
Vipin Kumar8c075ef2015-05-19 18:03:53 -0700310 nroute = ospf6_route_next (route);
hasso508e53e2004-05-18 18:57:06 +0000311 if (route->type != OSPF6_DEST_TYPE_NETWORK)
312 continue;
313 if (route->path.origin.type != lsa->header->type)
314 continue;
315 if (route->path.origin.id != lsa->header->id)
316 continue;
317 if (route->path.origin.adv_router != lsa->header->adv_router)
318 continue;
319
hasso1e058382004-09-01 21:36:14 +0000320 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
hasso508e53e2004-05-18 18:57:06 +0000321 {
322 prefix2str (&route->prefix, buf, sizeof (buf));
hassoc6487d62004-12-24 06:00:11 +0000323 zlog_debug ("AS-External route remove: %s", buf);
hasso508e53e2004-05-18 18:57:06 +0000324 }
325 ospf6_route_remove (route, ospf6->route_table);
326 }
Christian Frankec78a46c2013-03-20 10:50:09 +0000327 if (route != NULL)
328 ospf6_route_unlock (route);
hasso508e53e2004-05-18 18:57:06 +0000329}
330
331void
332ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
333{
hasso508e53e2004-05-18 18:57:06 +0000334 struct ospf6_lsa *lsa;
335 u_int16_t type;
336 u_int32_t router;
337
Paul Jakmacb4b8842006-05-15 10:39:30 +0000338 if (! CHECK_FLAG (asbr_entry->flag, OSPF6_ROUTE_BEST))
hasso508e53e2004-05-18 18:57:06 +0000339 {
Paul Jakmacb4b8842006-05-15 10:39:30 +0000340 char buf[16];
341 inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (&asbr_entry->prefix),
342 buf, sizeof (buf));
343 zlog_info ("ignore non-best path: lsentry %s add", buf);
344 return;
hasso508e53e2004-05-18 18:57:06 +0000345 }
346
347 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
348 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
Paul Jakmacb4b8842006-05-15 10:39:30 +0000349 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb); lsa;
350 lsa = ospf6_lsdb_type_router_next (type, router, lsa))
hasso508e53e2004-05-18 18:57:06 +0000351 {
352 if (! OSPF6_LSA_IS_MAXAGE (lsa))
353 ospf6_asbr_lsa_add (lsa);
354 }
hasso508e53e2004-05-18 18:57:06 +0000355}
356
357void
358ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
359{
hasso508e53e2004-05-18 18:57:06 +0000360 struct ospf6_lsa *lsa;
361 u_int16_t type;
362 u_int32_t router;
363
hasso508e53e2004-05-18 18:57:06 +0000364 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
365 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
366 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
367 lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
368 ospf6_asbr_lsa_remove (lsa);
hasso508e53e2004-05-18 18:57:06 +0000369}
370
371
David Lamparter6b0655a2014-06-04 06:53:35 +0200372
paul718e3742002-12-13 20:15:29 +0000373/* redistribute function */
hasso508e53e2004-05-18 18:57:06 +0000374
Paul Jakma6ac29a52008-08-15 13:45:30 +0100375static void
paul0c083ee2004-10-10 12:54:58 +0000376ospf6_asbr_routemap_set (int type, const char *mapname)
paul718e3742002-12-13 20:15:29 +0000377{
hasso508e53e2004-05-18 18:57:06 +0000378 if (ospf6->rmap[type].name)
379 free (ospf6->rmap[type].name);
380 ospf6->rmap[type].name = strdup (mapname);
381 ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
paul718e3742002-12-13 20:15:29 +0000382}
383
Paul Jakma6ac29a52008-08-15 13:45:30 +0100384static void
paul718e3742002-12-13 20:15:29 +0000385ospf6_asbr_routemap_unset (int type)
386{
hasso508e53e2004-05-18 18:57:06 +0000387 if (ospf6->rmap[type].name)
388 free (ospf6->rmap[type].name);
389 ospf6->rmap[type].name = NULL;
390 ospf6->rmap[type].map = NULL;
paul718e3742002-12-13 20:15:29 +0000391}
392
Paul Jakma6ac29a52008-08-15 13:45:30 +0100393static void
paul0c083ee2004-10-10 12:54:58 +0000394ospf6_asbr_routemap_update (const char *mapname)
paul718e3742002-12-13 20:15:29 +0000395{
hasso508e53e2004-05-18 18:57:06 +0000396 int type;
397
398 if (ospf6 == NULL)
399 return;
400
401 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000402 {
hasso508e53e2004-05-18 18:57:06 +0000403 if (ospf6->rmap[type].name)
404 ospf6->rmap[type].map =
405 route_map_lookup_by_name (ospf6->rmap[type].name);
paul718e3742002-12-13 20:15:29 +0000406 else
hasso508e53e2004-05-18 18:57:06 +0000407 ospf6->rmap[type].map = NULL;
408 }
409}
410
411int
412ospf6_asbr_is_asbr (struct ospf6 *o)
413{
414 return o->external_table->count;
415}
416
Paul Jakma6ac29a52008-08-15 13:45:30 +0100417static void
hasso508e53e2004-05-18 18:57:06 +0000418ospf6_asbr_redistribute_set (int type)
419{
420 ospf6_zebra_redistribute (type);
421}
422
Paul Jakma6ac29a52008-08-15 13:45:30 +0100423static void
hasso508e53e2004-05-18 18:57:06 +0000424ospf6_asbr_redistribute_unset (int type)
425{
426 struct ospf6_route *route;
427 struct ospf6_external_info *info;
428
429 ospf6_zebra_no_redistribute (type);
430
431 for (route = ospf6_route_head (ospf6->external_table); route;
432 route = ospf6_route_next (route))
433 {
434 info = route->route_option;
435 if (info->type != type)
436 continue;
437
438 ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
439 &route->prefix);
440 }
Christian Franked9628722013-03-08 21:47:35 +0100441
442 ospf6_asbr_routemap_unset (type);
hasso508e53e2004-05-18 18:57:06 +0000443}
444
445void
Paul Jakma9099f9b2016-01-18 10:12:10 +0000446ospf6_asbr_redistribute_add (int type, ifindex_t ifindex, struct prefix *prefix,
Christian Franke7ae2b602016-10-01 06:41:40 +0200447 u_int nexthop_num, struct in6_addr *nexthop, route_tag_t tag)
hasso508e53e2004-05-18 18:57:06 +0000448{
449 int ret;
450 struct ospf6_route troute;
451 struct ospf6_external_info tinfo;
452 struct ospf6_route *route, *match;
453 struct ospf6_external_info *info;
454 struct prefix prefix_id;
455 struct route_node *node;
456 char pbuf[64], ibuf[16];
paul1eb8ef22005-04-07 07:30:20 +0000457 struct listnode *lnode, *lnnode;
hasso508e53e2004-05-18 18:57:06 +0000458 struct ospf6_area *oa;
459
460 if (! ospf6_zebra_is_redistribute (type))
461 return;
462
463 if (IS_OSPF6_DEBUG_ASBR)
464 {
465 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000466 zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
hasso508e53e2004-05-18 18:57:06 +0000467 }
468
469 /* if route-map was specified but not found, do not advertise */
470 if (ospf6->rmap[type].name)
471 {
472 if (ospf6->rmap[type].map == NULL)
hasso03d52f82004-09-29 00:26:19 +0000473 ospf6_asbr_routemap_update (NULL);
hasso508e53e2004-05-18 18:57:06 +0000474 if (ospf6->rmap[type].map == NULL)
475 {
476 zlog_warn ("route-map \"%s\" not found, suppress redistributing",
477 ospf6->rmap[type].name);
478 return;
479 }
480 }
481
482 /* apply route-map */
483 if (ospf6->rmap[type].map)
484 {
485 memset (&troute, 0, sizeof (troute));
486 memset (&tinfo, 0, sizeof (tinfo));
487 troute.route_option = &tinfo;
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +0400488 tinfo.ifindex = ifindex;
Christian Franke7ae2b602016-10-01 06:41:40 +0200489 tinfo.tag = tag;
hasso508e53e2004-05-18 18:57:06 +0000490
491 ret = route_map_apply (ospf6->rmap[type].map, prefix,
492 RMAP_OSPF6, &troute);
paul47828742005-08-10 15:46:11 +0000493 if (ret == RMAP_DENYMATCH)
hasso508e53e2004-05-18 18:57:06 +0000494 {
495 if (IS_OSPF6_DEBUG_ASBR)
hassoc6487d62004-12-24 06:00:11 +0000496 zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
hasso508e53e2004-05-18 18:57:06 +0000497 return;
498 }
499 }
500
501 match = ospf6_route_lookup (prefix, ospf6->external_table);
502 if (match)
503 {
504 info = match->route_option;
505
506 /* copy result of route-map */
507 if (ospf6->rmap[type].map)
508 {
509 if (troute.path.metric_type)
510 match->path.metric_type = troute.path.metric_type;
511 if (troute.path.cost)
512 match->path.cost = troute.path.cost;
513 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
514 memcpy (&info->forwarding, &tinfo.forwarding,
515 sizeof (struct in6_addr));
Christian Franke7ae2b602016-10-01 06:41:40 +0200516 info->tag = tinfo.tag;
517 }
518 else
519 {
520 /* If there is no route-map, simply update the tag */
521 info->tag = tag;
hasso508e53e2004-05-18 18:57:06 +0000522 }
523
524 info->type = type;
525 match->nexthop[0].ifindex = ifindex;
526 if (nexthop_num && nexthop)
527 memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
528
529 /* create/update binding in external_id_table */
530 prefix_id.family = AF_INET;
531 prefix_id.prefixlen = 32;
532 prefix_id.u.prefix4.s_addr = htonl (info->id);
533 node = route_node_get (ospf6->external_id_table, &prefix_id);
534 node->info = match;
535
536 if (IS_OSPF6_DEBUG_ASBR)
537 {
538 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000539 zlog_debug ("Advertise as AS-External Id:%s", ibuf);
hasso508e53e2004-05-18 18:57:06 +0000540 }
541
hasso3b687352004-08-19 06:56:53 +0000542 match->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000543 ospf6_as_external_lsa_originate (match);
hasso508e53e2004-05-18 18:57:06 +0000544 return;
545 }
546
547 /* create new entry */
548 route = ospf6_route_create ();
549 route->type = OSPF6_DEST_TYPE_NETWORK;
550 memcpy (&route->prefix, prefix, sizeof (struct prefix));
551
552 info = (struct ospf6_external_info *)
Stephen Hemminger393deb92008-08-18 14:13:29 -0700553 XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
hasso508e53e2004-05-18 18:57:06 +0000554 route->route_option = info;
555 info->id = ospf6->external_id++;
556
557 /* copy result of route-map */
558 if (ospf6->rmap[type].map)
559 {
560 if (troute.path.metric_type)
561 route->path.metric_type = troute.path.metric_type;
562 if (troute.path.cost)
563 route->path.cost = troute.path.cost;
564 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
565 memcpy (&info->forwarding, &tinfo.forwarding,
566 sizeof (struct in6_addr));
Christian Franke7ae2b602016-10-01 06:41:40 +0200567 info->tag = tinfo.tag;
568 }
569 else
570 {
571 /* If there is no route-map, simply set the tag */
572 info->tag = tag;
hasso508e53e2004-05-18 18:57:06 +0000573 }
574
575 info->type = type;
576 route->nexthop[0].ifindex = ifindex;
577 if (nexthop_num && nexthop)
578 memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
579
580 /* create/update binding in external_id_table */
581 prefix_id.family = AF_INET;
582 prefix_id.prefixlen = 32;
583 prefix_id.u.prefix4.s_addr = htonl (info->id);
584 node = route_node_get (ospf6->external_id_table, &prefix_id);
585 node->info = route;
586
587 route = ospf6_route_add (route, ospf6->external_table);
588 route->route_option = info;
589
590 if (IS_OSPF6_DEBUG_ASBR)
591 {
592 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000593 zlog_debug ("Advertise as AS-External Id:%s", ibuf);
hasso508e53e2004-05-18 18:57:06 +0000594 }
595
hasso3b687352004-08-19 06:56:53 +0000596 route->path.origin.id = htonl (info->id);
hasso6452df02004-08-15 05:52:07 +0000597 ospf6_as_external_lsa_originate (route);
hasso508e53e2004-05-18 18:57:06 +0000598
599 /* Router-Bit (ASBR Flag) may have to be updated */
paul1eb8ef22005-04-07 07:30:20 +0000600 for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
601 OSPF6_ROUTER_LSA_SCHEDULE (oa);
hasso508e53e2004-05-18 18:57:06 +0000602}
603
604void
Paul Jakma9099f9b2016-01-18 10:12:10 +0000605ospf6_asbr_redistribute_remove (int type, ifindex_t ifindex,
606 struct prefix *prefix)
hasso508e53e2004-05-18 18:57:06 +0000607{
608 struct ospf6_route *match;
609 struct ospf6_external_info *info = NULL;
610 struct route_node *node;
611 struct ospf6_lsa *lsa;
612 struct prefix prefix_id;
613 char pbuf[64], ibuf[16];
paul1eb8ef22005-04-07 07:30:20 +0000614 struct listnode *lnode, *lnnode;
hasso508e53e2004-05-18 18:57:06 +0000615 struct ospf6_area *oa;
616
617 match = ospf6_route_lookup (prefix, ospf6->external_table);
618 if (match == NULL)
619 {
620 if (IS_OSPF6_DEBUG_ASBR)
621 {
622 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000623 zlog_debug ("No such route %s to withdraw", pbuf);
hasso508e53e2004-05-18 18:57:06 +0000624 }
625 return;
626 }
627
628 info = match->route_option;
629 assert (info);
630
631 if (info->type != type)
632 {
633 if (IS_OSPF6_DEBUG_ASBR)
634 {
635 prefix2str (prefix, pbuf, sizeof (pbuf));
hassoc6487d62004-12-24 06:00:11 +0000636 zlog_debug ("Original protocol mismatch: %s", pbuf);
hasso508e53e2004-05-18 18:57:06 +0000637 }
638 return;
639 }
640
641 if (IS_OSPF6_DEBUG_ASBR)
642 {
643 prefix2str (prefix, pbuf, sizeof (pbuf));
644 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
hassoc6487d62004-12-24 06:00:11 +0000645 zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
hasso508e53e2004-05-18 18:57:06 +0000646 }
647
648 lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
649 htonl (info->id), ospf6->router_id, ospf6->lsdb);
650 if (lsa)
hasso6452df02004-08-15 05:52:07 +0000651 ospf6_lsa_purge (lsa);
hasso508e53e2004-05-18 18:57:06 +0000652
653 /* remove binding in external_id_table */
654 prefix_id.family = AF_INET;
655 prefix_id.prefixlen = 32;
656 prefix_id.u.prefix4.s_addr = htonl (info->id);
657 node = route_node_lookup (ospf6->external_id_table, &prefix_id);
658 assert (node);
659 node->info = NULL;
660 route_unlock_node (node);
661
662 ospf6_route_remove (match, ospf6->external_table);
663 XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
664
665 /* Router-Bit (ASBR Flag) may have to be updated */
paul1eb8ef22005-04-07 07:30:20 +0000666 for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
667 OSPF6_ROUTER_LSA_SCHEDULE (oa);
paul718e3742002-12-13 20:15:29 +0000668}
669
670DEFUN (ospf6_redistribute,
671 ospf6_redistribute_cmd,
David Lampartere0ca5fd2009-09-16 01:52:42 +0200672 "redistribute " QUAGGA_REDIST_STR_OSPF6D,
paul718e3742002-12-13 20:15:29 +0000673 "Redistribute\n"
David Lampartere0ca5fd2009-09-16 01:52:42 +0200674 QUAGGA_REDIST_HELP_STR_OSPF6D
paul718e3742002-12-13 20:15:29 +0000675 )
676{
David Lampartere0ca5fd2009-09-16 01:52:42 +0200677 int type;
paul718e3742002-12-13 20:15:29 +0000678
David Lampartere0ca5fd2009-09-16 01:52:42 +0200679 type = proto_redistnum(AFI_IP6, argv[0]);
680 if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
681 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000682
hasso508e53e2004-05-18 18:57:06 +0000683 ospf6_asbr_redistribute_unset (type);
hasso508e53e2004-05-18 18:57:06 +0000684 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000685 return CMD_SUCCESS;
686}
687
688DEFUN (ospf6_redistribute_routemap,
689 ospf6_redistribute_routemap_cmd,
David Lampartere0ca5fd2009-09-16 01:52:42 +0200690 "redistribute " QUAGGA_REDIST_STR_OSPF6D " route-map WORD",
paul718e3742002-12-13 20:15:29 +0000691 "Redistribute\n"
David Lampartere0ca5fd2009-09-16 01:52:42 +0200692 QUAGGA_REDIST_HELP_STR_OSPF6D
paul718e3742002-12-13 20:15:29 +0000693 "Route map reference\n"
694 "Route map name\n"
695 )
696{
David Lampartere0ca5fd2009-09-16 01:52:42 +0200697 int type;
paul718e3742002-12-13 20:15:29 +0000698
David Lampartere0ca5fd2009-09-16 01:52:42 +0200699 type = proto_redistnum(AFI_IP6, argv[0]);
700 if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
701 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000702
hasso508e53e2004-05-18 18:57:06 +0000703 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000704 ospf6_asbr_routemap_set (type, argv[1]);
hasso508e53e2004-05-18 18:57:06 +0000705 ospf6_asbr_redistribute_set (type);
paul718e3742002-12-13 20:15:29 +0000706 return CMD_SUCCESS;
707}
708
709DEFUN (no_ospf6_redistribute,
710 no_ospf6_redistribute_cmd,
David Lampartere0ca5fd2009-09-16 01:52:42 +0200711 "no redistribute " QUAGGA_REDIST_STR_OSPF6D,
paul718e3742002-12-13 20:15:29 +0000712 NO_STR
713 "Redistribute\n"
David Lampartere0ca5fd2009-09-16 01:52:42 +0200714 QUAGGA_REDIST_HELP_STR_OSPF6D
paul718e3742002-12-13 20:15:29 +0000715 )
716{
David Lampartere0ca5fd2009-09-16 01:52:42 +0200717 int type;
paul718e3742002-12-13 20:15:29 +0000718
David Lampartere0ca5fd2009-09-16 01:52:42 +0200719 type = proto_redistnum(AFI_IP6, argv[0]);
720 if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
721 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000722
hasso508e53e2004-05-18 18:57:06 +0000723 ospf6_asbr_redistribute_unset (type);
paul718e3742002-12-13 20:15:29 +0000724
paul718e3742002-12-13 20:15:29 +0000725 return CMD_SUCCESS;
726}
727
Daniel Walton69424be2015-05-19 18:03:41 -0700728ALIAS (no_ospf6_redistribute,
729 no_ospf6_redistribute_route_map_cmd,
730 "no redistribute " QUAGGA_REDIST_STR_OSPF6D " route-map WORD",
731 NO_STR
732 "Redistribute\n"
733 QUAGGA_REDIST_HELP_STR_OSPF6D
734 "Route map reference\n"
735 "Route map name\n")
736
paul718e3742002-12-13 20:15:29 +0000737int
738ospf6_redistribute_config_write (struct vty *vty)
739{
hasso508e53e2004-05-18 18:57:06 +0000740 int type;
paul718e3742002-12-13 20:15:29 +0000741
hasso508e53e2004-05-18 18:57:06 +0000742 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000743 {
hasso508e53e2004-05-18 18:57:06 +0000744 if (type == ZEBRA_ROUTE_OSPF6)
745 continue;
746 if (! ospf6_zebra_is_redistribute (type))
paul718e3742002-12-13 20:15:29 +0000747 continue;
748
hasso508e53e2004-05-18 18:57:06 +0000749 if (ospf6->rmap[type].name)
paul718e3742002-12-13 20:15:29 +0000750 vty_out (vty, " redistribute %s route-map %s%s",
hasso049207c2004-08-04 20:02:13 +0000751 ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
paul718e3742002-12-13 20:15:29 +0000752 else
753 vty_out (vty, " redistribute %s%s",
hasso049207c2004-08-04 20:02:13 +0000754 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000755 }
756
757 return 0;
758}
759
Paul Jakma6ac29a52008-08-15 13:45:30 +0100760static void
paul718e3742002-12-13 20:15:29 +0000761ospf6_redistribute_show_config (struct vty *vty)
762{
hasso508e53e2004-05-18 18:57:06 +0000763 int type;
764 int nroute[ZEBRA_ROUTE_MAX];
765 int total;
766 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000767 struct ospf6_external_info *info;
paul718e3742002-12-13 20:15:29 +0000768
hasso508e53e2004-05-18 18:57:06 +0000769 total = 0;
770 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
771 nroute[type] = 0;
772 for (route = ospf6_route_head (ospf6->external_table); route;
773 route = ospf6_route_next (route))
paul718e3742002-12-13 20:15:29 +0000774 {
hasso508e53e2004-05-18 18:57:06 +0000775 info = route->route_option;
776 nroute[info->type]++;
777 total++;
paul718e3742002-12-13 20:15:29 +0000778 }
779
hasso049207c2004-08-04 20:02:13 +0000780 vty_out (vty, "Redistributing External Routes from:%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000781 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
paul718e3742002-12-13 20:15:29 +0000782 {
hasso508e53e2004-05-18 18:57:06 +0000783 if (type == ZEBRA_ROUTE_OSPF6)
784 continue;
785 if (! ospf6_zebra_is_redistribute (type))
hassoe26bbeb2003-05-25 21:39:29 +0000786 continue;
787
hasso508e53e2004-05-18 18:57:06 +0000788 if (ospf6->rmap[type].name)
789 vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
790 ZROUTE_NAME (type), ospf6->rmap[type].name,
791 (ospf6->rmap[type].map ? "" : " (not found !)"),
hasso049207c2004-08-04 20:02:13 +0000792 VNL);
paul718e3742002-12-13 20:15:29 +0000793 else
hasso508e53e2004-05-18 18:57:06 +0000794 vty_out (vty, " %d: %s%s", nroute[type],
hasso049207c2004-08-04 20:02:13 +0000795 ZROUTE_NAME (type), VNL);
paul718e3742002-12-13 20:15:29 +0000796 }
hasso049207c2004-08-04 20:02:13 +0000797 vty_out (vty, "Total %d routes%s", total, VNL);
hasso508e53e2004-05-18 18:57:06 +0000798}
paul718e3742002-12-13 20:15:29 +0000799
paul718e3742002-12-13 20:15:29 +0000800
David Lamparter6b0655a2014-06-04 06:53:35 +0200801
hasso508e53e2004-05-18 18:57:06 +0000802/* Routemap Functions */
Paul Jakma6ac29a52008-08-15 13:45:30 +0100803static route_map_result_t
hasso508e53e2004-05-18 18:57:06 +0000804ospf6_routemap_rule_match_address_prefixlist (void *rule,
805 struct prefix *prefix,
806 route_map_object_t type,
807 void *object)
808{
809 struct prefix_list *plist;
paul718e3742002-12-13 20:15:29 +0000810
hasso508e53e2004-05-18 18:57:06 +0000811 if (type != RMAP_OSPF6)
812 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000813
hasso508e53e2004-05-18 18:57:06 +0000814 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
815 if (plist == NULL)
816 return RMAP_NOMATCH;
paul718e3742002-12-13 20:15:29 +0000817
hasso508e53e2004-05-18 18:57:06 +0000818 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
819 RMAP_NOMATCH : RMAP_MATCH);
820}
paul718e3742002-12-13 20:15:29 +0000821
Paul Jakma6ac29a52008-08-15 13:45:30 +0100822static void *
paul0c083ee2004-10-10 12:54:58 +0000823ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000824{
825 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000826}
827
Paul Jakma6ac29a52008-08-15 13:45:30 +0100828static void
hasso508e53e2004-05-18 18:57:06 +0000829ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000830{
hasso508e53e2004-05-18 18:57:06 +0000831 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
832}
paul718e3742002-12-13 20:15:29 +0000833
hasso508e53e2004-05-18 18:57:06 +0000834struct route_map_rule_cmd
835ospf6_routemap_rule_match_address_prefixlist_cmd =
836{
837 "ipv6 address prefix-list",
838 ospf6_routemap_rule_match_address_prefixlist,
839 ospf6_routemap_rule_match_address_prefixlist_compile,
840 ospf6_routemap_rule_match_address_prefixlist_free,
841};
hassoe26bbeb2003-05-25 21:39:29 +0000842
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +0400843/* `match interface IFNAME' */
844/* Match function should return 1 if match is success else return
845 zero. */
846static route_map_result_t
847ospf6_routemap_rule_match_interface (void *rule, struct prefix *prefix,
848 route_map_object_t type, void *object)
849{
850 struct interface *ifp;
851 struct ospf6_external_info *ei;
852
853 if (type == RMAP_OSPF6)
854 {
855 ei = ((struct ospf6_route *) object)->route_option;
856 ifp = if_lookup_by_name ((char *)rule);
857
858 if (ifp != NULL
859 && ei->ifindex == ifp->ifindex)
860 return RMAP_MATCH;
861 }
862
863 return RMAP_NOMATCH;
864}
865
866/* Route map `interface' match statement. `arg' should be
867 interface name. */
868static void *
869ospf6_routemap_rule_match_interface_compile (const char *arg)
870{
871 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
872}
873
874/* Free route map's compiled `interface' value. */
875static void
876ospf6_routemap_rule_match_interface_free (void *rule)
877{
878 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
879}
880
881/* Route map commands for interface matching. */
882struct route_map_rule_cmd
883ospf6_routemap_rule_match_interface_cmd =
884{
885 "interface",
886 ospf6_routemap_rule_match_interface,
887 ospf6_routemap_rule_match_interface_compile,
888 ospf6_routemap_rule_match_interface_free
889};
890
Christian Franke7ae2b602016-10-01 06:41:40 +0200891/* Match function for matching route tags */
892static route_map_result_t
893ospf6_routemap_rule_match_tag (void *rule, struct prefix *prefix,
894 route_map_object_t type, void *object)
895{
896 route_tag_t *tag = rule;
897 struct ospf6_route *route = object;
898 struct ospf6_external_info *info = route->route_option;
899
900 if (type == RMAP_OSPF6 && info->tag == *tag)
901 return RMAP_MATCH;
902
903 return RMAP_NOMATCH;
904}
905
906static struct route_map_rule_cmd
907ospf6_routemap_rule_match_tag_cmd =
908{
909 "tag",
910 ospf6_routemap_rule_match_tag,
911 route_map_rule_tag_compile,
912 route_map_rule_tag_free,
913};
914
Paul Jakma6ac29a52008-08-15 13:45:30 +0100915static route_map_result_t
hasso508e53e2004-05-18 18:57:06 +0000916ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
917 route_map_object_t type, void *object)
918{
919 char *metric_type = rule;
920 struct ospf6_route *route = object;
hassoe26bbeb2003-05-25 21:39:29 +0000921
hasso508e53e2004-05-18 18:57:06 +0000922 if (type != RMAP_OSPF6)
923 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000924
hasso508e53e2004-05-18 18:57:06 +0000925 if (strcmp (metric_type, "type-2") == 0)
926 route->path.metric_type = 2;
paul718e3742002-12-13 20:15:29 +0000927 else
hasso508e53e2004-05-18 18:57:06 +0000928 route->path.metric_type = 1;
paul718e3742002-12-13 20:15:29 +0000929
hasso508e53e2004-05-18 18:57:06 +0000930 return RMAP_OKAY;
931}
paul718e3742002-12-13 20:15:29 +0000932
Paul Jakma6ac29a52008-08-15 13:45:30 +0100933static void *
paul0c083ee2004-10-10 12:54:58 +0000934ospf6_routemap_rule_set_metric_type_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000935{
936 if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
937 return NULL;
938 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000939}
940
Paul Jakma6ac29a52008-08-15 13:45:30 +0100941static void
hasso508e53e2004-05-18 18:57:06 +0000942ospf6_routemap_rule_set_metric_type_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000943{
hasso508e53e2004-05-18 18:57:06 +0000944 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
945}
paul718e3742002-12-13 20:15:29 +0000946
hasso508e53e2004-05-18 18:57:06 +0000947struct route_map_rule_cmd
948ospf6_routemap_rule_set_metric_type_cmd =
949{
950 "metric-type",
951 ospf6_routemap_rule_set_metric_type,
952 ospf6_routemap_rule_set_metric_type_compile,
953 ospf6_routemap_rule_set_metric_type_free,
954};
paul718e3742002-12-13 20:15:29 +0000955
Paul Jakma6ac29a52008-08-15 13:45:30 +0100956static route_map_result_t
hasso508e53e2004-05-18 18:57:06 +0000957ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
958 route_map_object_t type, void *object)
959{
960 char *metric = rule;
961 struct ospf6_route *route = object;
paul718e3742002-12-13 20:15:29 +0000962
hasso508e53e2004-05-18 18:57:06 +0000963 if (type != RMAP_OSPF6)
964 return RMAP_OKAY;
paul718e3742002-12-13 20:15:29 +0000965
hasso508e53e2004-05-18 18:57:06 +0000966 route->path.cost = atoi (metric);
967 return RMAP_OKAY;
968}
paul718e3742002-12-13 20:15:29 +0000969
Paul Jakma6ac29a52008-08-15 13:45:30 +0100970static void *
paul0c083ee2004-10-10 12:54:58 +0000971ospf6_routemap_rule_set_metric_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +0000972{
973 u_int32_t metric;
974 char *endp;
975 metric = strtoul (arg, &endp, 0);
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700976 if (metric > OSPF_LS_INFINITY || *endp != '\0')
hasso508e53e2004-05-18 18:57:06 +0000977 return NULL;
978 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
paul718e3742002-12-13 20:15:29 +0000979}
980
Paul Jakma6ac29a52008-08-15 13:45:30 +0100981static void
hasso508e53e2004-05-18 18:57:06 +0000982ospf6_routemap_rule_set_metric_free (void *rule)
paul718e3742002-12-13 20:15:29 +0000983{
hasso508e53e2004-05-18 18:57:06 +0000984 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
985}
986
987struct route_map_rule_cmd
988ospf6_routemap_rule_set_metric_cmd =
989{
990 "metric",
991 ospf6_routemap_rule_set_metric,
992 ospf6_routemap_rule_set_metric_compile,
993 ospf6_routemap_rule_set_metric_free,
994};
995
Paul Jakma6ac29a52008-08-15 13:45:30 +0100996static route_map_result_t
hasso508e53e2004-05-18 18:57:06 +0000997ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
998 route_map_object_t type, void *object)
999{
1000 char *forwarding = rule;
1001 struct ospf6_route *route = object;
1002 struct ospf6_external_info *info = route->route_option;
1003
1004 if (type != RMAP_OSPF6)
1005 return RMAP_OKAY;
1006
1007 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
1008 {
1009 memset (&info->forwarding, 0, sizeof (struct in6_addr));
1010 return RMAP_ERROR;
1011 }
1012
1013 return RMAP_OKAY;
1014}
1015
Paul Jakma6ac29a52008-08-15 13:45:30 +01001016static void *
paul0c083ee2004-10-10 12:54:58 +00001017ospf6_routemap_rule_set_forwarding_compile (const char *arg)
hasso508e53e2004-05-18 18:57:06 +00001018{
1019 struct in6_addr a;
1020 if (inet_pton (AF_INET6, arg, &a) != 1)
1021 return NULL;
1022 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1023}
1024
Paul Jakma6ac29a52008-08-15 13:45:30 +01001025static void
hasso508e53e2004-05-18 18:57:06 +00001026ospf6_routemap_rule_set_forwarding_free (void *rule)
1027{
1028 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1029}
1030
1031struct route_map_rule_cmd
1032ospf6_routemap_rule_set_forwarding_cmd =
1033{
1034 "forwarding-address",
1035 ospf6_routemap_rule_set_forwarding,
1036 ospf6_routemap_rule_set_forwarding_compile,
1037 ospf6_routemap_rule_set_forwarding_free,
1038};
1039
Christian Franke7ae2b602016-10-01 06:41:40 +02001040static route_map_result_t
1041ospf6_routemap_rule_set_tag (void *rule, struct prefix *prefix,
1042 route_map_object_t type, void *object)
1043{
1044 route_tag_t *tag = rule;
1045 struct ospf6_route *route = object;
1046 struct ospf6_external_info *info = route->route_option;
1047
1048 if (type != RMAP_OSPF6)
1049 return RMAP_OKAY;
1050
1051 info->tag = *tag;
1052 return RMAP_OKAY;
1053}
1054
1055static struct route_map_rule_cmd
1056ospf6_routemap_rule_set_tag_cmd =
1057{
1058 "tag",
1059 ospf6_routemap_rule_set_tag,
1060 route_map_rule_tag_compile,
1061 route_map_rule_tag_free,
1062};
1063
Paul Jakma6ac29a52008-08-15 13:45:30 +01001064static int
hasso508e53e2004-05-18 18:57:06 +00001065route_map_command_status (struct vty *vty, int ret)
1066{
1067 if (! ret)
1068 return CMD_SUCCESS;
1069
1070 switch (ret)
1071 {
1072 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07001073 vty_out (vty, "OSPF6 Can't find rule.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001074 break;
1075 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07001076 vty_out (vty, "OSPF6 Argument is malformed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001077 break;
1078 default:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07001079 vty_out (vty, "OSPF6 route-map add set failed.%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001080 break;
1081 }
1082 return CMD_WARNING;
1083}
1084
1085/* add "match address" */
1086DEFUN (ospf6_routemap_match_address_prefixlist,
1087 ospf6_routemap_match_address_prefixlist_cmd,
1088 "match ipv6 address prefix-list WORD",
1089 "Match values\n"
1090 IPV6_STR
1091 "Match address of route\n"
1092 "Match entries of prefix-lists\n"
1093 "IPv6 prefix-list name\n")
1094{
1095 int ret = route_map_add_match ((struct route_map_index *) vty->index,
1096 "ipv6 address prefix-list", argv[0]);
1097 return route_map_command_status (vty, ret);
1098}
1099
1100/* delete "match address" */
1101DEFUN (ospf6_routemap_no_match_address_prefixlist,
1102 ospf6_routemap_no_match_address_prefixlist_cmd,
1103 "no match ipv6 address prefix-list WORD",
1104 NO_STR
1105 "Match values\n"
1106 IPV6_STR
1107 "Match address of route\n"
1108 "Match entries of prefix-lists\n"
1109 "IPv6 prefix-list name\n")
1110{
1111 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1112 "ipv6 address prefix-list", argv[0]);
1113 return route_map_command_status (vty, ret);
1114}
1115
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +04001116/* "match interface" */
1117DEFUN (ospf6_routemap_match_interface,
1118 ospf6_routemap_match_interface_cmd,
1119 "match interface WORD",
1120 MATCH_STR
1121 "Match first hop interface of route\n"
1122 "Interface name\n")
1123{
1124 return route_map_add_match ((struct route_map_index *) vty->index,
1125 "interface", argv[0]);
1126}
1127
1128/* "no match interface WORD" */
1129DEFUN (ospf6_routemap_no_match_interface,
1130 ospf6_routemap_no_match_interface_cmd,
1131 "no match interface",
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +04001132 NO_STR
Christian Franke7ae2b602016-10-01 06:41:40 +02001133 MATCH_STR
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +04001134 "Match first hop interface of route\n")
1135{
1136 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1137 "interface", (argc == 0) ? NULL : argv[0]);
1138 return route_map_command_status (vty, ret);
1139}
1140
1141ALIAS (ospf6_routemap_no_match_interface,
1142 ospf6_routemap_no_match_interface_val_cmd,
1143 "no match interface WORD",
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +04001144 NO_STR
Christian Franke7ae2b602016-10-01 06:41:40 +02001145 MATCH_STR
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +04001146 "Match first hop interface of route\n"
1147 "Interface name\n")
1148
Christian Franke7ae2b602016-10-01 06:41:40 +02001149/* add "match tag" */
1150DEFUN (ospf6_routemap_match_tag,
1151 ospf6_routemap_match_tag_cmd,
1152 "match tag <1-4294967295>",
1153 MATCH_STR
1154 "Tag value for routing protocol\n"
1155 "Tag value\n")
1156{
1157 int ret = route_map_add_match ((struct route_map_index *) vty->index,
1158 "tag", argv[0]);
1159 return route_map_command_status (vty, ret);
1160}
1161
1162/* delete "match tag" */
1163DEFUN (ospf6_routemap_no_match_tag,
1164 ospf6_routemap_no_match_tag_cmd,
1165 "no match tag",
1166 NO_STR
1167 MATCH_STR
1168 "Tag value for routing protocol\n")
1169{
1170 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1171 "tag", argc ? argv[0] : NULL);
1172 return route_map_command_status (vty, ret);
1173}
1174
1175ALIAS (ospf6_routemap_no_match_tag,
1176 ospf6_routemap_no_match_tag_val_cmd,
1177 "no match tag <1-4294967295>",
1178 NO_STR
1179 MATCH_STR
1180 "Tag value for routing protocol\n"
1181 "Tag value\n")
1182
hasso508e53e2004-05-18 18:57:06 +00001183/* add "set metric-type" */
1184DEFUN (ospf6_routemap_set_metric_type,
1185 ospf6_routemap_set_metric_type_cmd,
1186 "set metric-type (type-1|type-2)",
1187 "Set value\n"
1188 "Type of metric\n"
1189 "OSPF6 external type 1 metric\n"
1190 "OSPF6 external type 2 metric\n")
1191{
1192 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1193 "metric-type", argv[0]);
1194 return route_map_command_status (vty, ret);
1195}
1196
1197/* delete "set metric-type" */
1198DEFUN (ospf6_routemap_no_set_metric_type,
1199 ospf6_routemap_no_set_metric_type_cmd,
1200 "no set metric-type (type-1|type-2)",
1201 NO_STR
1202 "Set value\n"
1203 "Type of metric\n"
1204 "OSPF6 external type 1 metric\n"
1205 "OSPF6 external type 2 metric\n")
1206{
1207 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1208 "metric-type", argv[0]);
1209 return route_map_command_status (vty, ret);
1210}
1211
1212/* add "set metric" */
1213DEFUN (set_metric,
1214 set_metric_cmd,
1215 "set metric <0-4294967295>",
1216 "Set value\n"
1217 "Metric value\n"
1218 "Metric value\n")
1219{
1220 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1221 "metric", argv[0]);
1222 return route_map_command_status (vty, ret);
1223}
1224
1225/* delete "set metric" */
1226DEFUN (no_set_metric,
1227 no_set_metric_cmd,
Daniel Walton62f936e2015-11-09 20:21:59 -05001228 "no set metric",
hasso508e53e2004-05-18 18:57:06 +00001229 NO_STR
Daniel Walton62f936e2015-11-09 20:21:59 -05001230 SET_STR
1231 "Metric value for destination routing protocol\n")
hasso508e53e2004-05-18 18:57:06 +00001232{
Daniel Walton62f936e2015-11-09 20:21:59 -05001233 int ret = 0;
1234
1235 if (argc == 0)
1236 ret = route_map_delete_set ((struct route_map_index *) vty->index,
1237 "metric", NULL);
1238 else
1239 ret = route_map_delete_set ((struct route_map_index *) vty->index,
1240 "metric", argv[0]);
hasso508e53e2004-05-18 18:57:06 +00001241 return route_map_command_status (vty, ret);
1242}
1243
Daniel Walton62f936e2015-11-09 20:21:59 -05001244ALIAS (no_set_metric,
1245 no_set_metric_val_cmd,
1246 "no set metric <0-4294967295>",
1247 NO_STR
1248 SET_STR
1249 "Metric value for destination routing protocol\n"
1250 "Metric value\n")
1251
hasso508e53e2004-05-18 18:57:06 +00001252/* add "set forwarding-address" */
1253DEFUN (ospf6_routemap_set_forwarding,
1254 ospf6_routemap_set_forwarding_cmd,
1255 "set forwarding-address X:X::X:X",
1256 "Set value\n"
1257 "Forwarding Address\n"
1258 "IPv6 Address\n")
1259{
1260 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1261 "forwarding-address", argv[0]);
1262 return route_map_command_status (vty, ret);
1263}
1264
1265/* delete "set forwarding-address" */
1266DEFUN (ospf6_routemap_no_set_forwarding,
1267 ospf6_routemap_no_set_forwarding_cmd,
1268 "no set forwarding-address X:X::X:X",
1269 NO_STR
1270 "Set value\n"
1271 "Forwarding Address\n"
1272 "IPv6 Address\n")
1273{
1274 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1275 "forwarding-address", argv[0]);
1276 return route_map_command_status (vty, ret);
1277}
1278
Christian Franke7ae2b602016-10-01 06:41:40 +02001279/* add "set tag" */
1280DEFUN (ospf6_routemap_set_tag,
1281 ospf6_routemap_set_tag_cmd,
1282 "set tag <1-4294967295>",
1283 "Set value\n"
1284 "Tag value for routing protocol\n"
1285 "Tag value\n")
1286{
1287 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1288 "tag", argv[0]);
1289 return route_map_command_status (vty, ret);
1290}
1291
1292/* delete "set tag" */
1293DEFUN (ospf6_routemap_no_set_tag,
1294 ospf6_routemap_no_set_tag_cmd,
1295 "no set tag",
1296 NO_STR
1297 "Set value\n"
1298 "Tag value for routing protocol\n")
1299{
1300 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1301 "tag", argc ? argv[0] : NULL);
1302 return route_map_command_status (vty, ret);
1303}
1304
1305ALIAS (ospf6_routemap_no_set_tag,
1306 ospf6_routemap_no_set_tag_val_cmd,
1307 "no set tag <1-4294967295>",
1308 NO_STR
1309 "Set value\n"
1310 "Tag value for routing protocol\n"
1311 "Tag value\n")
1312
Paul Jakma6ac29a52008-08-15 13:45:30 +01001313static void
1314ospf6_routemap_init (void)
hasso508e53e2004-05-18 18:57:06 +00001315{
1316 route_map_init ();
1317 route_map_init_vty ();
1318 route_map_add_hook (ospf6_asbr_routemap_update);
1319 route_map_delete_hook (ospf6_asbr_routemap_update);
1320
1321 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +04001322 route_map_install_match (&ospf6_routemap_rule_match_interface_cmd);
Christian Franke7ae2b602016-10-01 06:41:40 +02001323 route_map_install_match (&ospf6_routemap_rule_match_tag_cmd);
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +04001324
hasso508e53e2004-05-18 18:57:06 +00001325 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
1326 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
1327 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
Christian Franke7ae2b602016-10-01 06:41:40 +02001328 route_map_install_set (&ospf6_routemap_rule_set_tag_cmd);
hasso508e53e2004-05-18 18:57:06 +00001329
1330 /* Match address prefix-list */
1331 install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
1332 install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
1333
Vyacheslav Trushkin42a7deb2011-11-16 14:22:03 +04001334 /* Match interface */
1335 install_element (RMAP_NODE, &ospf6_routemap_match_interface_cmd);
1336 install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_cmd);
1337 install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_val_cmd);
1338
Christian Franke7ae2b602016-10-01 06:41:40 +02001339 /* Match tag */
1340 install_element (RMAP_NODE, &ospf6_routemap_match_tag_cmd);
1341 install_element (RMAP_NODE, &ospf6_routemap_no_match_tag_cmd);
1342 install_element (RMAP_NODE, &ospf6_routemap_no_match_tag_val_cmd);
1343
hasso508e53e2004-05-18 18:57:06 +00001344 /* ASE Metric Type (e.g. Type-1/Type-2) */
1345 install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
1346 install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
1347
1348 /* ASE Metric */
1349 install_element (RMAP_NODE, &set_metric_cmd);
1350 install_element (RMAP_NODE, &no_set_metric_cmd);
Daniel Walton62f936e2015-11-09 20:21:59 -05001351 install_element (RMAP_NODE, &no_set_metric_val_cmd);
hasso508e53e2004-05-18 18:57:06 +00001352
Christian Franke7ae2b602016-10-01 06:41:40 +02001353 /* Forwarding address */
hasso508e53e2004-05-18 18:57:06 +00001354 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
1355 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
Christian Franke7ae2b602016-10-01 06:41:40 +02001356
1357 /* Tag */
1358 install_element (RMAP_NODE, &ospf6_routemap_set_tag_cmd);
1359 install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_cmd);
1360 install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_val_cmd);
hasso508e53e2004-05-18 18:57:06 +00001361}
1362
David Lamparter6b0655a2014-06-04 06:53:35 +02001363
hasso508e53e2004-05-18 18:57:06 +00001364/* Display functions */
Dinesh Dutte68a6762013-08-25 03:03:23 +00001365static char *
1366ospf6_as_external_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
1367 int buflen, int pos)
1368{
1369 struct ospf6_as_external_lsa *external;
1370 struct in6_addr in6;
1371 int prefix_length = 0;
1372
1373 if (lsa)
1374 {
1375 external = (struct ospf6_as_external_lsa *)
1376 OSPF6_LSA_HEADER_END (lsa->header);
1377
1378 if (pos == 0)
1379 {
1380 ospf6_prefix_in6_addr (&in6, &external->prefix);
1381 prefix_length = external->prefix.prefix_length;
1382 }
1383 else {
1384 in6 = *((struct in6_addr *)
1385 ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
1386 OSPF6_PREFIX_SPACE (external->prefix.prefix_length)));
1387 }
1388 if (buf)
1389 {
1390 inet_ntop (AF_INET6, &in6, buf, buflen);
1391 if (prefix_length)
1392 sprintf (&buf[strlen(buf)], "/%d", prefix_length);
1393 }
1394 }
1395 return (buf);
1396}
1397
Paul Jakma6ac29a52008-08-15 13:45:30 +01001398static int
hasso508e53e2004-05-18 18:57:06 +00001399ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
1400{
1401 struct ospf6_as_external_lsa *external;
paul718e3742002-12-13 20:15:29 +00001402 char buf[64];
paul718e3742002-12-13 20:15:29 +00001403
1404 assert (lsa->header);
hasso508e53e2004-05-18 18:57:06 +00001405 external = (struct ospf6_as_external_lsa *)
1406 OSPF6_LSA_HEADER_END (lsa->header);
paul718e3742002-12-13 20:15:29 +00001407
1408 /* bits */
hasso508e53e2004-05-18 18:57:06 +00001409 snprintf (buf, sizeof (buf), "%c%c%c",
1410 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
1411 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
1412 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
paul718e3742002-12-13 20:15:29 +00001413
hasso049207c2004-08-04 20:02:13 +00001414 vty_out (vty, " Bits: %s%s", buf, VNL);
hasso508e53e2004-05-18 18:57:06 +00001415 vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
hasso049207c2004-08-04 20:02:13 +00001416 VNL);
paul718e3742002-12-13 20:15:29 +00001417
hasso508e53e2004-05-18 18:57:06 +00001418 ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1419 buf, sizeof (buf));
1420 vty_out (vty, " Prefix Options: %s%s", buf,
hasso049207c2004-08-04 20:02:13 +00001421 VNL);
paul718e3742002-12-13 20:15:29 +00001422
1423 vty_out (vty, " Referenced LSType: %d%s",
hasso508e53e2004-05-18 18:57:06 +00001424 ntohs (external->prefix.prefix_refer_lstype),
hasso049207c2004-08-04 20:02:13 +00001425 VNL);
paul718e3742002-12-13 20:15:29 +00001426
Dinesh Dutte68a6762013-08-25 03:03:23 +00001427 vty_out (vty, " Prefix: %s%s",
1428 ospf6_as_external_lsa_get_prefix_str (lsa, buf, sizeof(buf), 0), VNL);
paul718e3742002-12-13 20:15:29 +00001429
1430 /* Forwarding-Address */
1431 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
1432 {
Dinesh Dutte68a6762013-08-25 03:03:23 +00001433 vty_out (vty, " Forwarding-Address: %s%s",
1434 ospf6_as_external_lsa_get_prefix_str (lsa, buf, sizeof(buf), 1),
1435 VNL);
paul718e3742002-12-13 20:15:29 +00001436 }
1437
Christian Franke7ae2b602016-10-01 06:41:40 +02001438 /* Tag */
1439 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T))
1440 {
1441 vty_out (vty, " Tag: %u%s",
1442 ospf6_as_external_lsa_get_tag (lsa), VNL);
1443 }
1444
paul718e3742002-12-13 20:15:29 +00001445 return 0;
1446}
1447
Paul Jakma6ac29a52008-08-15 13:45:30 +01001448static void
hasso508e53e2004-05-18 18:57:06 +00001449ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +00001450{
hasso508e53e2004-05-18 18:57:06 +00001451 struct ospf6_external_info *info = route->route_option;
1452 char prefix[64], id[16], forwarding[64];
1453 u_int32_t tmp_id;
1454
1455 prefix2str (&route->prefix, prefix, sizeof (prefix));
1456 tmp_id = ntohl (info->id);
1457 inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
1458 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
1459 inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
1460 else
1461 snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
1462 route->nexthop[0].ifindex);
1463
ajsf52d13c2005-10-01 17:38:06 +00001464 vty_out (vty, "%c %-32s %-15s type-%d %5lu %s%s",
1465 zebra_route_char(info->type),
hasso508e53e2004-05-18 18:57:06 +00001466 prefix, id, route->path.metric_type,
1467 (u_long) (route->path.metric_type == 2 ?
1468 route->path.cost_e2 : route->path.cost),
hasso049207c2004-08-04 20:02:13 +00001469 forwarding, VNL);
paul718e3742002-12-13 20:15:29 +00001470}
1471
hasso508e53e2004-05-18 18:57:06 +00001472DEFUN (show_ipv6_ospf6_redistribute,
1473 show_ipv6_ospf6_redistribute_cmd,
1474 "show ipv6 ospf6 redistribute",
paul718e3742002-12-13 20:15:29 +00001475 SHOW_STR
1476 IP6_STR
paul718e3742002-12-13 20:15:29 +00001477 OSPF6_STR
1478 "redistributing External information\n"
1479 )
1480{
hasso508e53e2004-05-18 18:57:06 +00001481 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +00001482
Vipin Kumarf972dec2015-05-19 18:03:41 -07001483 OSPF6_CMD_CHECK_RUNNING ();
1484
hasso508e53e2004-05-18 18:57:06 +00001485 ospf6_redistribute_show_config (vty);
1486
1487 for (route = ospf6_route_head (ospf6->external_table); route;
1488 route = ospf6_route_next (route))
1489 ospf6_asbr_external_route_show (vty, route);
1490
paul718e3742002-12-13 20:15:29 +00001491 return CMD_SUCCESS;
1492}
1493
hasso6452df02004-08-15 05:52:07 +00001494struct ospf6_lsa_handler as_external_handler =
hasso508e53e2004-05-18 18:57:06 +00001495{
hasso6452df02004-08-15 05:52:07 +00001496 OSPF6_LSTYPE_AS_EXTERNAL,
1497 "AS-External",
Dinesh Dutte68a6762013-08-25 03:03:23 +00001498 "ASE",
1499 ospf6_as_external_lsa_show,
1500 ospf6_as_external_lsa_get_prefix_str
hasso6452df02004-08-15 05:52:07 +00001501};
hasso508e53e2004-05-18 18:57:06 +00001502
paul718e3742002-12-13 20:15:29 +00001503void
Paul Jakma6ac29a52008-08-15 13:45:30 +01001504ospf6_asbr_init (void)
paul718e3742002-12-13 20:15:29 +00001505{
hasso508e53e2004-05-18 18:57:06 +00001506 ospf6_routemap_init ();
paul718e3742002-12-13 20:15:29 +00001507
hasso6452df02004-08-15 05:52:07 +00001508 ospf6_install_lsa_handler (&as_external_handler);
paul718e3742002-12-13 20:15:29 +00001509
hasso508e53e2004-05-18 18:57:06 +00001510 install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
hasso508e53e2004-05-18 18:57:06 +00001511
paul718e3742002-12-13 20:15:29 +00001512 install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
1513 install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
1514 install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
Daniel Walton69424be2015-05-19 18:03:41 -07001515 install_element (OSPF6_NODE, &no_ospf6_redistribute_route_map_cmd);
paul718e3742002-12-13 20:15:29 +00001516}
1517
Tom Goffae2254a2010-11-10 13:01:41 -08001518void
Christian Franked9628722013-03-08 21:47:35 +01001519ospf6_asbr_redistribute_reset (void)
1520{
1521 int type;
1522
1523 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
1524 {
1525 if (type == ZEBRA_ROUTE_OSPF6)
1526 continue;
1527 if (ospf6_zebra_is_redistribute (type))
1528 ospf6_asbr_redistribute_unset(type);
1529 }
1530}
1531
1532void
Tom Goffae2254a2010-11-10 13:01:41 -08001533ospf6_asbr_terminate (void)
1534{
1535 route_map_finish ();
1536}
paul718e3742002-12-13 20:15:29 +00001537
hasso508e53e2004-05-18 18:57:06 +00001538DEFUN (debug_ospf6_asbr,
1539 debug_ospf6_asbr_cmd,
1540 "debug ospf6 asbr",
1541 DEBUG_STR
1542 OSPF6_STR
1543 "Debug OSPFv3 ASBR function\n"
1544 )
1545{
1546 OSPF6_DEBUG_ASBR_ON ();
1547 return CMD_SUCCESS;
1548}
1549
1550DEFUN (no_debug_ospf6_asbr,
1551 no_debug_ospf6_asbr_cmd,
1552 "no debug ospf6 asbr",
1553 NO_STR
1554 DEBUG_STR
1555 OSPF6_STR
1556 "Debug OSPFv3 ASBR function\n"
1557 )
1558{
1559 OSPF6_DEBUG_ASBR_OFF ();
1560 return CMD_SUCCESS;
1561}
1562
1563int
1564config_write_ospf6_debug_asbr (struct vty *vty)
1565{
1566 if (IS_OSPF6_DEBUG_ASBR)
hasso049207c2004-08-04 20:02:13 +00001567 vty_out (vty, "debug ospf6 asbr%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001568 return 0;
1569}
1570
1571void
1572install_element_ospf6_debug_asbr ()
1573{
1574 install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
1575 install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
1576 install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
1577 install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
1578}
1579
1580