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