blob: 832f17c9515b86b102a8a03e7acd27452184f369 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* RIPng routemap.
2 * Copyright (C) 1999 Kunihiro Ishiguro
3 *
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 Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "if.h"
25#include "memory.h"
26#include "prefix.h"
27#include "routemap.h"
28#include "command.h"
29
30#include "ripngd/ripngd.h"
31
32#if 0
33/* `match interface IFNAME' */
34route_map_result_t
35route_match_interface (void *rule, struct prefix *prefix,
36 route_map_object_t type, void *object)
37{
38 struct ripng_info *rinfo;
39 struct interface *ifp;
40 char *ifname;
41
42 if (type == ROUTE_MAP_RIPNG)
43 {
44 ifname = rule;
45 ifp = if_lookup_by_name(ifname);
46
47 if (!ifp)
48 return RM_NOMATCH;
49
50 rinfo = object;
51
52 if (rinfo->ifindex == ifp->ifindex)
53 return RM_MATCH;
54 else
55 return RM_NOMATCH;
56 }
57 return RM_NOMATCH;
58}
59
60void *
61route_match_interface_compile (char *arg)
62{
63 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
64}
65
66void
67route_match_interface_free (void *rule)
68{
69 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
70}
71
72struct route_map_rule_cmd route_match_interface_cmd =
73{
74 "interface",
75 route_match_interface,
76 route_match_interface_compile,
77 route_match_interface_free
78};
79#endif /* 0 */
80
81struct rip_metric_modifier
82{
83 enum
84 {
85 metric_increment,
86 metric_decrement,
87 metric_absolute
88 } type;
89
90 u_char metric;
91};
92
93route_map_result_t
94route_set_metric (void *rule, struct prefix *prefix,
95 route_map_object_t type, void *object)
96{
97 if (type == RMAP_RIPNG)
98 {
99 struct rip_metric_modifier *mod;
100 struct ripng_info *rinfo;
101
102 mod = rule;
103 rinfo = object;
104
105 if (mod->type == metric_increment)
106 rinfo->metric += mod->metric;
107 else if (mod->type == metric_decrement)
108 rinfo->metric -= mod->metric;
109 else if (mod->type == metric_absolute)
110 rinfo->metric = mod->metric;
111
112 if (rinfo->metric < 1)
113 rinfo->metric = 1;
114 if (rinfo->metric > RIPNG_METRIC_INFINITY)
115 rinfo->metric = RIPNG_METRIC_INFINITY;
116
117 rinfo->metric_set = 1;
118 }
119 return RMAP_OKAY;
120}
121
122void *
123route_set_metric_compile (char *arg)
124{
125 int len;
126 char *pnt;
127 int type;
128 long metric;
129 char *endptr = NULL;
130 struct rip_metric_modifier *mod;
131
132 len = strlen (arg);
133 pnt = arg;
134
135 if (len == 0)
136 return NULL;
137
138 /* Examine first character. */
139 if (arg[0] == '+')
140 {
141 type = metric_increment;
142 pnt++;
143 }
144 else if (arg[0] == '-')
145 {
146 type = metric_decrement;
147 pnt++;
148 }
149 else
150 type = metric_absolute;
151
152 /* Check beginning with digit string. */
153 if (*pnt < '0' || *pnt > '9')
154 return NULL;
155
156 /* Convert string to integer. */
157 metric = strtol (pnt, &endptr, 10);
158
159 if (metric == LONG_MAX || *endptr != '\0')
160 return NULL;
paul73ffb252003-04-19 15:49:49 +0000161 /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
162 /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
163 if (metric < 0)
paul718e3742002-12-13 20:15:29 +0000164 return NULL;
165
166 mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
167 sizeof (struct rip_metric_modifier));
168 mod->type = type;
169 mod->metric = metric;
170
171 return mod;
172}
173
174void
175route_set_metric_free (void *rule)
176{
177 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
178}
179
180struct route_map_rule_cmd route_set_metric_cmd =
181{
182 "metric",
183 route_set_metric,
184 route_set_metric_compile,
185 route_set_metric_free,
186};
187
188int
189ripng_route_match_add (struct vty *vty, struct route_map_index *index,
190 char *command, char *arg)
191{
192 int ret;
193
194 ret = route_map_add_match (index, command, arg);
195 if (ret)
196 {
197 switch (ret)
198 {
199 case RMAP_RULE_MISSING:
200 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
201 return CMD_WARNING;
202 break;
203 case RMAP_COMPILE_ERROR:
204 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
205 return CMD_WARNING;
206 break;
207 }
208 }
209 return CMD_SUCCESS;
210}
211
212int
213ripng_route_match_delete (struct vty *vty, struct route_map_index *index,
214 char *command, char *arg)
215{
216 int ret;
217
218 ret = route_map_delete_match (index, command, arg);
219 if (ret)
220 {
221 switch (ret)
222 {
223 case RMAP_RULE_MISSING:
224 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
225 return CMD_WARNING;
226 break;
227 case RMAP_COMPILE_ERROR:
228 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
229 return CMD_WARNING;
230 break;
231 }
232 }
233 return CMD_SUCCESS;
234}
235
236int
237ripng_route_set_add (struct vty *vty, struct route_map_index *index,
238 char *command, char *arg)
239{
240 int ret;
241
242 ret = route_map_add_set (index, command, arg);
243 if (ret)
244 {
245 switch (ret)
246 {
247 case RMAP_RULE_MISSING:
248 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
249 return CMD_WARNING;
250 break;
251 case RMAP_COMPILE_ERROR:
252 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
253 return CMD_WARNING;
254 break;
255 }
256 }
257 return CMD_SUCCESS;
258}
259
260int
261ripng_route_set_delete (struct vty *vty, struct route_map_index *index,
262 char *command, char *arg)
263{
264 int ret;
265
266 ret = route_map_delete_set (index, command, arg);
267 if (ret)
268 {
269 switch (ret)
270 {
271 case RMAP_RULE_MISSING:
272 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
273 return CMD_WARNING;
274 break;
275 case RMAP_COMPILE_ERROR:
276 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
277 return CMD_WARNING;
278 break;
279 }
280 }
281 return CMD_SUCCESS;
282}
283
284#if 0
285DEFUN (match_interface,
286 match_interface_cmd,
287 "match interface WORD",
288 "Match value\n"
289 "Interface\n"
290 "Interface name\n")
291{
292 return ripng_route_match_add (vty, vty->index, "interface", argv[0]);
293}
294
295DEFUN (no_match_interface,
296 no_match_interface_cmd,
297 "no match interface WORD",
298 NO_STR
299 "Match value\n"
300 "Interface\n"
301 "Interface name\n")
302{
303 return ripng_route_match_delete (vty, vty->index, "interface", argv[0]);
304}
305#endif /* 0 */
306
307DEFUN (set_metric,
308 set_metric_cmd,
309 "set metric <0-4294967295>",
310 "Set value\n"
311 "Metric\n"
312 "METRIC value\n")
313{
314 return ripng_route_set_add (vty, vty->index, "metric", argv[0]);
315}
316
317DEFUN (no_set_metric,
318 no_set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +0000319 "no set metric",
paul718e3742002-12-13 20:15:29 +0000320 NO_STR
paul73ffb252003-04-19 15:49:49 +0000321 SET_STR
322 "Metric value for destination routing protocol\n")
paul718e3742002-12-13 20:15:29 +0000323{
paul73ffb252003-04-19 15:49:49 +0000324 if (argc == 0)
325 return ripng_route_set_delete (vty, vty->index, "metric", NULL);
326
paul718e3742002-12-13 20:15:29 +0000327 return ripng_route_set_delete (vty, vty->index, "metric", argv[0]);
328}
329
paul73ffb252003-04-19 15:49:49 +0000330ALIAS (no_set_metric,
331 no_set_metric_val_cmd,
332 "no set metric <0-4294967295>",
333 NO_STR
334 SET_STR
335 "Metric value for destination routing protocol\n"
336 "Metric value\n")
337
paul718e3742002-12-13 20:15:29 +0000338void
339ripng_route_map_init ()
340{
341 route_map_init ();
342 route_map_init_vty ();
343
344 /* route_map_install_match (&route_match_interface_cmd); */
345 route_map_install_set (&route_set_metric_cmd);
346
347 /*
348 install_element (RMAP_NODE, &match_interface_cmd);
349 install_element (RMAP_NODE, &no_match_interface_cmd);
350 */
351
352 install_element (RMAP_NODE, &set_metric_cmd);
353 install_element (RMAP_NODE, &no_set_metric_cmd);
354}