blob: f237e6b6b693175028d5ff6e3322f87a25617202 [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;
161 if (metric < 0 || metric > RIPNG_METRIC_INFINITY)
162 return NULL;
163
164 mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
165 sizeof (struct rip_metric_modifier));
166 mod->type = type;
167 mod->metric = metric;
168
169 return mod;
170}
171
172void
173route_set_metric_free (void *rule)
174{
175 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
176}
177
178struct route_map_rule_cmd route_set_metric_cmd =
179{
180 "metric",
181 route_set_metric,
182 route_set_metric_compile,
183 route_set_metric_free,
184};
185
186int
187ripng_route_match_add (struct vty *vty, struct route_map_index *index,
188 char *command, char *arg)
189{
190 int ret;
191
192 ret = route_map_add_match (index, command, arg);
193 if (ret)
194 {
195 switch (ret)
196 {
197 case RMAP_RULE_MISSING:
198 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
199 return CMD_WARNING;
200 break;
201 case RMAP_COMPILE_ERROR:
202 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
203 return CMD_WARNING;
204 break;
205 }
206 }
207 return CMD_SUCCESS;
208}
209
210int
211ripng_route_match_delete (struct vty *vty, struct route_map_index *index,
212 char *command, char *arg)
213{
214 int ret;
215
216 ret = route_map_delete_match (index, command, arg);
217 if (ret)
218 {
219 switch (ret)
220 {
221 case RMAP_RULE_MISSING:
222 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
223 return CMD_WARNING;
224 break;
225 case RMAP_COMPILE_ERROR:
226 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
227 return CMD_WARNING;
228 break;
229 }
230 }
231 return CMD_SUCCESS;
232}
233
234int
235ripng_route_set_add (struct vty *vty, struct route_map_index *index,
236 char *command, char *arg)
237{
238 int ret;
239
240 ret = route_map_add_set (index, command, arg);
241 if (ret)
242 {
243 switch (ret)
244 {
245 case RMAP_RULE_MISSING:
246 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
247 return CMD_WARNING;
248 break;
249 case RMAP_COMPILE_ERROR:
250 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
251 return CMD_WARNING;
252 break;
253 }
254 }
255 return CMD_SUCCESS;
256}
257
258int
259ripng_route_set_delete (struct vty *vty, struct route_map_index *index,
260 char *command, char *arg)
261{
262 int ret;
263
264 ret = route_map_delete_set (index, command, arg);
265 if (ret)
266 {
267 switch (ret)
268 {
269 case RMAP_RULE_MISSING:
270 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
271 return CMD_WARNING;
272 break;
273 case RMAP_COMPILE_ERROR:
274 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
275 return CMD_WARNING;
276 break;
277 }
278 }
279 return CMD_SUCCESS;
280}
281
282#if 0
283DEFUN (match_interface,
284 match_interface_cmd,
285 "match interface WORD",
286 "Match value\n"
287 "Interface\n"
288 "Interface name\n")
289{
290 return ripng_route_match_add (vty, vty->index, "interface", argv[0]);
291}
292
293DEFUN (no_match_interface,
294 no_match_interface_cmd,
295 "no match interface WORD",
296 NO_STR
297 "Match value\n"
298 "Interface\n"
299 "Interface name\n")
300{
301 return ripng_route_match_delete (vty, vty->index, "interface", argv[0]);
302}
303#endif /* 0 */
304
305DEFUN (set_metric,
306 set_metric_cmd,
307 "set metric <0-4294967295>",
308 "Set value\n"
309 "Metric\n"
310 "METRIC value\n")
311{
312 return ripng_route_set_add (vty, vty->index, "metric", argv[0]);
313}
314
315DEFUN (no_set_metric,
316 no_set_metric_cmd,
317 "no set metric <0-4294967295>",
318 NO_STR
319 "Set value\n"
320 "Metric\n"
321 "METRIC value\n")
322{
323 return ripng_route_set_delete (vty, vty->index, "metric", argv[0]);
324}
325
326void
327ripng_route_map_init ()
328{
329 route_map_init ();
330 route_map_init_vty ();
331
332 /* route_map_install_match (&route_match_interface_cmd); */
333 route_map_install_set (&route_set_metric_cmd);
334
335 /*
336 install_element (RMAP_NODE, &match_interface_cmd);
337 install_element (RMAP_NODE, &no_match_interface_cmd);
338 */
339
340 install_element (RMAP_NODE, &set_metric_cmd);
341 install_element (RMAP_NODE, &no_set_metric_cmd);
342}