blob: f617e9133b7ba740a796abc6aac3b024cfbe370e [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPFv3 Route-Map
3 * Copyright (C) 1999 Yasuhiro Ohara
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "log.h"
26#include "memory.h"
27#include "linklist.h"
28#include "prefix.h"
29#include "command.h"
30#include "vty.h"
31#include "routemap.h"
32#include "table.h"
33#include "plist.h"
34
35#include "ospf6_route.h"
36#include "ospf6_prefix.h"
37#include "ospf6_lsa.h"
38#include "ospf6_asbr.h"
39
40route_map_result_t
41ospf6_routemap_rule_match_address_prefixlist (void *rule,
42 struct prefix *prefix,
43 route_map_object_t type,
44 void *object)
45{
46 struct prefix_list *plist;
47
48 if (type != RMAP_OSPF6)
49 return RMAP_NOMATCH;
50
51 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
52
53 if (plist == NULL)
54 return RMAP_NOMATCH;
55
56 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
57 RMAP_NOMATCH : RMAP_MATCH);
58}
59
60void *
61ospf6_routemap_rule_match_address_prefixlist_compile (char *arg)
62{
63 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
64}
65
66void
67ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
68{
69 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
70}
71
72struct route_map_rule_cmd
73ospf6_routemap_rule_match_address_prefixlist_cmd =
74{
75 "ipv6 address prefix-list",
76 ospf6_routemap_rule_match_address_prefixlist,
77 ospf6_routemap_rule_match_address_prefixlist_compile,
78 ospf6_routemap_rule_match_address_prefixlist_free,
79};
80
81route_map_result_t
82ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
83 route_map_object_t type, void *object)
84{
85 char *metric_type = rule;
86 struct ospf6_external_info *info = object;
87
88 if (type != RMAP_OSPF6)
89 return RMAP_OKAY;
90
91 if (strcmp (metric_type, "type-2") == 0)
92 info->metric_type = 2;
93 else
94 info->metric_type = 1;
95
96 return RMAP_OKAY;
97}
98
99void *
100ospf6_routemap_rule_set_metric_type_compile (char *arg)
101{
102 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
103}
104
105void
106ospf6_routemap_rule_set_metric_type_free (void *rule)
107{
108 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
109}
110
111struct route_map_rule_cmd
112ospf6_routemap_rule_set_metric_type_cmd =
113{
114 "metric-type",
115 ospf6_routemap_rule_set_metric_type,
116 ospf6_routemap_rule_set_metric_type_compile,
117 ospf6_routemap_rule_set_metric_type_free,
118};
119
120route_map_result_t
121ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
122 route_map_object_t type, void *object)
123{
124 char *metric = rule;
125 struct ospf6_external_info *info = object;
126
127 if (type != RMAP_OSPF6)
128 return RMAP_OKAY;
129
130 info->metric = atoi (metric);
131 return RMAP_OKAY;
132}
133
134void *
135ospf6_routemap_rule_set_metric_compile (char *arg)
136{
137 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
138}
139
140void
141ospf6_routemap_rule_set_metric_free (void *rule)
142{
143 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
144}
145
146struct route_map_rule_cmd
147ospf6_routemap_rule_set_metric_cmd =
148{
149 "metric",
150 ospf6_routemap_rule_set_metric,
151 ospf6_routemap_rule_set_metric_compile,
152 ospf6_routemap_rule_set_metric_free,
153};
154
155route_map_result_t
156ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
157 route_map_object_t type, void *object)
158{
159 char *forwarding = rule;
160 struct ospf6_external_info *info = object;
161
162 if (type != RMAP_OSPF6)
163 return RMAP_OKAY;
164
165 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
166 {
167 memset (&info->forwarding, 0, sizeof (struct in6_addr));
168 return RMAP_ERROR;
169 }
170
171 return RMAP_OKAY;
172}
173
174void *
175ospf6_routemap_rule_set_forwarding_compile (char *arg)
176{
177 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
178}
179
180void
181ospf6_routemap_rule_set_forwarding_free (void *rule)
182{
183 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
184}
185
186struct route_map_rule_cmd
187ospf6_routemap_rule_set_forwarding_cmd =
188{
189 "forwarding-address",
190 ospf6_routemap_rule_set_forwarding,
191 ospf6_routemap_rule_set_forwarding_compile,
192 ospf6_routemap_rule_set_forwarding_free,
193};
194
195int
196route_map_command_status (struct vty *vty, int ret)
197{
198 if (! ret)
199 return CMD_SUCCESS;
200
201 switch (ret)
202 {
203 case RMAP_RULE_MISSING:
204 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
205 break;
206 case RMAP_COMPILE_ERROR:
207 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
208 break;
209 default:
210 vty_out (vty, "route-map add set failed.%s", VTY_NEWLINE);
211 break;
212 }
213 return CMD_WARNING;
214}
215
216/* add "match address" */
paul73ffb252003-04-19 15:49:49 +0000217DEFUN (match_ipv6_address_prefix_list,
218 match_ipv6_address_prefix_list_cmd,
paul718e3742002-12-13 20:15:29 +0000219 "match ipv6 address prefix-list WORD",
paul73ffb252003-04-19 15:49:49 +0000220 MATCH_STR
paul718e3742002-12-13 20:15:29 +0000221 IPV6_STR
222 "Match address of route\n"
223 "Match entries of prefix-lists\n"
paul73ffb252003-04-19 15:49:49 +0000224 "IP prefix-list name\n")
paul718e3742002-12-13 20:15:29 +0000225{
226 int ret = route_map_add_match ((struct route_map_index *) vty->index,
227 "ipv6 address prefix-list", argv[0]);
228 return route_map_command_status (vty, ret);
229}
230
231/* delete "match address" */
paul73ffb252003-04-19 15:49:49 +0000232DEFUN (no_match_ipv6_address_prefix_list,
233 no_match_ipv6_address_prefix_list_cmd,
paul718e3742002-12-13 20:15:29 +0000234 "no match ipv6 address prefix-list WORD",
235 NO_STR
paul73ffb252003-04-19 15:49:49 +0000236 MATCH_STR
paul718e3742002-12-13 20:15:29 +0000237 IPV6_STR
238 "Match address of route\n"
239 "Match entries of prefix-lists\n"
paul73ffb252003-04-19 15:49:49 +0000240 "IP prefix-list name\n")
paul718e3742002-12-13 20:15:29 +0000241{
242 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
243 "ipv6 address prefix-list", argv[0]);
244 return route_map_command_status (vty, ret);
245}
246
247/* add "set metric-type" */
paul73ffb252003-04-19 15:49:49 +0000248DEFUN (set_metric_type,
249 set_metric_type_cmd,
paul718e3742002-12-13 20:15:29 +0000250 "set metric-type (type-1|type-2)",
paul73ffb252003-04-19 15:49:49 +0000251 SET_STR
252 "Type of metric for destination routing protocol\n"
253 "OSPF[6] external type 1 metric\n"
254 "OSPF[6] external type 2 metric\n")
paul718e3742002-12-13 20:15:29 +0000255{
256 int ret = route_map_add_set ((struct route_map_index *) vty->index,
257 "metric-type", argv[0]);
258 return route_map_command_status (vty, ret);
259}
260
261/* delete "set metric-type" */
paul73ffb252003-04-19 15:49:49 +0000262DEFUN (no_set_metric_type,
263 no_set_metric_type_cmd,
264 "no set metric-type",
paul718e3742002-12-13 20:15:29 +0000265 NO_STR
paul73ffb252003-04-19 15:49:49 +0000266 SET_STR
267 "Type of metric for destination routing protocol\n")
paul718e3742002-12-13 20:15:29 +0000268{
paul73ffb252003-04-19 15:49:49 +0000269 int ret;
270 if (argc == 0)
271 ret = route_map_delete_set ((struct route_map_index *) vty->index,
272 "metric-type", NULL);
273 else
274 ret = route_map_delete_set ((struct route_map_index *) vty->index,
paul718e3742002-12-13 20:15:29 +0000275 "metric-type", argv[0]);
276 return route_map_command_status (vty, ret);
277}
278
paul73ffb252003-04-19 15:49:49 +0000279ALIAS (no_set_metric_type,
280 no_set_metric_type_val_cmd,
281 "no set metric-type (type-1|type-2)",
282 NO_STR
283 SET_STR
284 "Type of metric for destination routing protocol\n"
285 "OSPF[6] external type 1 metric\n"
286 "OSPF[6] external type 2 metric\n")
287
paul718e3742002-12-13 20:15:29 +0000288/* add "set metric" */
289DEFUN (set_metric,
290 set_metric_cmd,
291 "set metric <0-4294967295>",
paul73ffb252003-04-19 15:49:49 +0000292 SET_STR
293 "Metric value for destination routing protocol\n"
paul718e3742002-12-13 20:15:29 +0000294 "Metric value\n")
295{
296 int ret = route_map_add_set ((struct route_map_index *) vty->index,
297 "metric", argv[0]);
298 return route_map_command_status (vty, ret);
299}
300
301/* delete "set metric" */
302DEFUN (no_set_metric,
303 no_set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +0000304 "no set metric",
paul718e3742002-12-13 20:15:29 +0000305 NO_STR
paul73ffb252003-04-19 15:49:49 +0000306 SET_STR
307 "Metric value for destination routing protocol\n")
paul718e3742002-12-13 20:15:29 +0000308{
paul73ffb252003-04-19 15:49:49 +0000309 int ret;
310 if (argc == 0)
311 ret = route_map_delete_set ((struct route_map_index *) vty->index,
312 "metric", NULL);
313 else
314 ret = route_map_delete_set ((struct route_map_index *) vty->index,
paul718e3742002-12-13 20:15:29 +0000315 "metric", argv[0]);
316 return route_map_command_status (vty, ret);
317}
318
paul73ffb252003-04-19 15:49:49 +0000319ALIAS (no_set_metric,
320 no_set_metric_val_cmd,
321 "no set metric <0-4294967295>",
322 NO_STR
323 SET_STR
324 "Metric value for destination routing protocol\n"
325 "Metric value\n")
326
paul718e3742002-12-13 20:15:29 +0000327/* add "set forwarding-address" */
328DEFUN (ospf6_routemap_set_forwarding,
329 ospf6_routemap_set_forwarding_cmd,
330 "set forwarding-address X:X::X:X",
331 "Set value\n"
332 "Forwarding Address\n"
333 "IPv6 Address\n")
334{
335 int ret = route_map_add_set ((struct route_map_index *) vty->index,
336 "forwarding-address", argv[0]);
337 return route_map_command_status (vty, ret);
338}
339
340/* delete "set forwarding-address" */
341DEFUN (ospf6_routemap_no_set_forwarding,
342 ospf6_routemap_no_set_forwarding_cmd,
343 "no set forwarding-address X:X::X:X",
344 NO_STR
345 "Set value\n"
346 "Forwarding Address\n"
347 "IPv6 Address\n")
348{
349 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
350 "forwarding-address", argv[0]);
351 return route_map_command_status (vty, ret);
352}
353
354void
355ospf6_routemap_init ()
356{
357 route_map_init ();
358 route_map_init_vty ();
359 route_map_add_hook (ospf6_asbr_routemap_update);
360 route_map_delete_hook (ospf6_asbr_routemap_update);
361
362 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
363 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
364 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
365 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
366
367 /* Match address prefix-list */
paul73ffb252003-04-19 15:49:49 +0000368 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
369 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +0000370
371 /* ASE Metric Type (e.g. Type-1/Type-2) */
paul73ffb252003-04-19 15:49:49 +0000372 install_element (RMAP_NODE, &set_metric_type_cmd);
373 install_element (RMAP_NODE, &no_set_metric_type_cmd);
374 install_element (RMAP_NODE, &no_set_metric_type_val_cmd);
paul718e3742002-12-13 20:15:29 +0000375
376 /* ASE Metric */
377 install_element (RMAP_NODE, &set_metric_cmd);
378 install_element (RMAP_NODE, &no_set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +0000379 install_element (RMAP_NODE, &no_set_metric_val_cmd);
paul718e3742002-12-13 20:15:29 +0000380
381 /* ASE Metric */
382 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
383 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
384}
385