]> git.proxmox.com Git - mirror_frr.git/blob - ripngd/ripng_routemap.c
Merge remote-tracking branch 'origin/stable/2.0'
[mirror_frr.git] / ripngd / ripng_routemap.c
1 /* 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 "vty.h"
28 #include "routemap.h"
29 #include "command.h"
30 #include "sockunion.h"
31
32 #include "ripngd/ripngd.h"
33
34 struct rip_metric_modifier
35 {
36 enum
37 {
38 metric_increment,
39 metric_decrement,
40 metric_absolute
41 } type;
42
43 u_char metric;
44 };
45
46 /* `match metric METRIC' */
47 /* Match function return 1 if match is success else return zero. */
48 static route_map_result_t
49 route_match_metric (void *rule, struct prefix *prefix,
50 route_map_object_t type, void *object)
51 {
52 u_int32_t *metric;
53 struct ripng_info *rinfo;
54
55 if (type == RMAP_RIPNG)
56 {
57 metric = rule;
58 rinfo = object;
59
60 if (rinfo->metric == *metric)
61 return RMAP_MATCH;
62 else
63 return RMAP_NOMATCH;
64 }
65 return RMAP_NOMATCH;
66 }
67
68 /* Route map `match metric' match statement. `arg' is METRIC value */
69 static void *
70 route_match_metric_compile (const char *arg)
71 {
72 u_int32_t *metric;
73
74 metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
75 *metric = atoi (arg);
76
77 if(*metric > 0)
78 return metric;
79
80 XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
81 return NULL;
82 }
83
84 /* Free route map's compiled `match metric' value. */
85 static void
86 route_match_metric_free (void *rule)
87 {
88 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
89 }
90
91 /* Route map commands for metric matching. */
92 static struct route_map_rule_cmd route_match_metric_cmd =
93 {
94 "metric",
95 route_match_metric,
96 route_match_metric_compile,
97 route_match_metric_free
98 };
99
100 /* `match interface IFNAME' */
101 /* Match function return 1 if match is success else return zero. */
102 static route_map_result_t
103 route_match_interface (void *rule, struct prefix *prefix,
104 route_map_object_t type, void *object)
105 {
106 struct ripng_info *rinfo;
107 struct interface *ifp;
108 char *ifname;
109
110 if (type == RMAP_RIPNG)
111 {
112 ifname = rule;
113 ifp = if_lookup_by_name(ifname);
114
115 if (!ifp)
116 return RMAP_NOMATCH;
117
118 rinfo = object;
119
120 if (rinfo->ifindex == ifp->ifindex)
121 return RMAP_MATCH;
122 else
123 return RMAP_NOMATCH;
124 }
125 return RMAP_NOMATCH;
126 }
127
128 /* Route map `match interface' match statement. `arg' is IFNAME value */
129 static void *
130 route_match_interface_compile (const char *arg)
131 {
132 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
133 }
134
135 static void
136 route_match_interface_free (void *rule)
137 {
138 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
139 }
140
141 static struct route_map_rule_cmd route_match_interface_cmd =
142 {
143 "interface",
144 route_match_interface,
145 route_match_interface_compile,
146 route_match_interface_free
147 };
148
149 /* `match tag TAG' */
150 /* Match function return 1 if match is success else return zero. */
151 static route_map_result_t
152 route_match_tag (void *rule, struct prefix *prefix,
153 route_map_object_t type, void *object)
154 {
155 route_tag_t *tag;
156 struct ripng_info *rinfo;
157 route_tag_t rinfo_tag;
158
159 if (type == RMAP_RIPNG)
160 {
161 tag = rule;
162 rinfo = object;
163
164 /* The information stored by rinfo is host ordered. */
165 rinfo_tag = rinfo->tag;
166 if (rinfo_tag == *tag)
167 return RMAP_MATCH;
168 else
169 return RMAP_NOMATCH;
170 }
171 return RMAP_NOMATCH;
172 }
173
174 static struct route_map_rule_cmd route_match_tag_cmd =
175 {
176 "tag",
177 route_match_tag,
178 route_map_rule_tag_compile,
179 route_map_rule_tag_free,
180 };
181
182 /* `set metric METRIC' */
183
184 /* Set metric to attribute. */
185 static route_map_result_t
186 route_set_metric (void *rule, struct prefix *prefix,
187 route_map_object_t type, void *object)
188 {
189 if (type == RMAP_RIPNG)
190 {
191 struct rip_metric_modifier *mod;
192 struct ripng_info *rinfo;
193
194 mod = rule;
195 rinfo = object;
196
197 if (mod->type == metric_increment)
198 rinfo->metric_out += mod->metric;
199 else if (mod->type == metric_decrement)
200 rinfo->metric_out-= mod->metric;
201 else if (mod->type == metric_absolute)
202 rinfo->metric_out = mod->metric;
203
204 if (rinfo->metric_out < 1)
205 rinfo->metric_out = 1;
206 if (rinfo->metric_out > RIPNG_METRIC_INFINITY)
207 rinfo->metric_out = RIPNG_METRIC_INFINITY;
208
209 rinfo->metric_set = 1;
210 }
211 return RMAP_OKAY;
212 }
213
214 /* set metric compilation. */
215 static void *
216 route_set_metric_compile (const char *arg)
217 {
218 int len;
219 const char *pnt;
220 int type;
221 long metric;
222 char *endptr = NULL;
223 struct rip_metric_modifier *mod;
224
225 len = strlen (arg);
226 pnt = arg;
227
228 if (len == 0)
229 return NULL;
230
231 /* Examine first character. */
232 if (arg[0] == '+')
233 {
234 type = metric_increment;
235 pnt++;
236 }
237 else if (arg[0] == '-')
238 {
239 type = metric_decrement;
240 pnt++;
241 }
242 else
243 type = metric_absolute;
244
245 /* Check beginning with digit string. */
246 if (*pnt < '0' || *pnt > '9')
247 return NULL;
248
249 /* Convert string to integer. */
250 metric = strtol (pnt, &endptr, 10);
251
252 if (metric == LONG_MAX || *endptr != '\0')
253 return NULL;
254 /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
255 /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
256 if (metric < 0)
257 return NULL;
258
259 mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
260 sizeof (struct rip_metric_modifier));
261 mod->type = type;
262 mod->metric = metric;
263
264 return mod;
265 }
266
267 /* Free route map's compiled `set metric' value. */
268 static void
269 route_set_metric_free (void *rule)
270 {
271 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
272 }
273
274 static struct route_map_rule_cmd route_set_metric_cmd =
275 {
276 "metric",
277 route_set_metric,
278 route_set_metric_compile,
279 route_set_metric_free,
280 };
281
282 /* `set ipv6 next-hop local IP_ADDRESS' */
283
284 /* Set nexthop to object. ojbect must be pointer to struct attr. */
285 static route_map_result_t
286 route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
287 route_map_object_t type, void *object)
288 {
289 struct in6_addr *address;
290 struct ripng_info *rinfo;
291
292 if(type == RMAP_RIPNG)
293 {
294 /* Fetch routemap's rule information. */
295 address = rule;
296 rinfo = object;
297
298 /* Set next hop value. */
299 rinfo->nexthop_out = *address;
300 }
301
302 return RMAP_OKAY;
303 }
304
305 /* Route map `ipv6 nexthop local' compile function. Given string is converted
306 to struct in6_addr structure. */
307 static void *
308 route_set_ipv6_nexthop_local_compile (const char *arg)
309 {
310 int ret;
311 struct in6_addr *address;
312
313 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
314
315 ret = inet_pton (AF_INET6, arg, address);
316
317 if (ret == 0)
318 {
319 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
320 return NULL;
321 }
322
323 return address;
324 }
325
326 /* Free route map's compiled `ipv6 nexthop local' value. */
327 static void
328 route_set_ipv6_nexthop_local_free (void *rule)
329 {
330 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
331 }
332
333 /* Route map commands for ipv6 nexthop local set. */
334 static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
335 {
336 "ipv6 next-hop local",
337 route_set_ipv6_nexthop_local,
338 route_set_ipv6_nexthop_local_compile,
339 route_set_ipv6_nexthop_local_free
340 };
341
342 /* `set tag TAG' */
343
344 /* Set tag to object. ojbect must be pointer to struct attr. */
345 static route_map_result_t
346 route_set_tag (void *rule, struct prefix *prefix,
347 route_map_object_t type, void *object)
348 {
349 route_tag_t *tag;
350 struct ripng_info *rinfo;
351
352 if(type == RMAP_RIPNG)
353 {
354 /* Fetch routemap's rule information. */
355 tag = rule;
356 rinfo = object;
357
358 /* Set next hop value. */
359 rinfo->tag_out = *tag;
360 }
361
362 return RMAP_OKAY;
363 }
364
365 /* Route map commands for tag set. */
366 static struct route_map_rule_cmd route_set_tag_cmd =
367 {
368 "tag",
369 route_set_tag,
370 route_map_rule_tag_compile,
371 route_map_rule_tag_free
372 };
373
374 #define MATCH_STR "Match values from routing table\n"
375 #define SET_STR "Set values in destination routing protocol\n"
376
377 void
378 ripng_route_map_reset ()
379 {
380 /* XXX ??? */
381 ;
382 }
383
384 void
385 ripng_route_map_init ()
386 {
387 route_map_init ();
388
389 route_map_match_interface_hook (generic_match_add);
390 route_map_no_match_interface_hook (generic_match_delete);
391
392 route_map_match_metric_hook (generic_match_add);
393 route_map_no_match_metric_hook (generic_match_delete);
394
395 route_map_match_tag_hook (generic_match_add);
396 route_map_no_match_tag_hook (generic_match_delete);
397
398 route_map_set_ipv6_nexthop_local_hook (generic_set_add);
399 route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete);
400
401 route_map_set_metric_hook (generic_set_add);
402 route_map_no_set_metric_hook (generic_set_delete);
403
404 route_map_set_tag_hook (generic_set_add);
405 route_map_no_set_tag_hook (generic_set_delete);
406
407 route_map_install_match (&route_match_metric_cmd);
408 route_map_install_match (&route_match_interface_cmd);
409 route_map_install_match (&route_match_tag_cmd);
410 route_map_install_set (&route_set_metric_cmd);
411 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
412 route_map_install_set (&route_set_tag_cmd);
413 }