]> git.proxmox.com Git - mirror_frr.git/blame - ripngd/ripng_routemap.c
Merge branch 'stable/3.0'
[mirror_frr.git] / ripngd / ripng_routemap.c
CommitLineData
718e3744 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 *
896014f4
DL
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
718e3744 19 */
20
21#include <zebra.h>
22
23#include "if.h"
24#include "memory.h"
25#include "prefix.h"
82f97584 26#include "vty.h"
718e3744 27#include "routemap.h"
28#include "command.h"
a94434b6 29#include "sockunion.h"
718e3744 30
31#include "ripngd/ripngd.h"
6b0655a2 32
a94434b6 33struct 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
a94434b6 45/* `match metric METRIC' */
46/* Match function return 1 if match is success else return zero. */
6ac29a51 47static route_map_result_t
a94434b6 48route_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 */
6ac29a51 68static void *
98b718a9 69route_match_metric_compile (const char *arg)
a94434b6 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. */
6ac29a51 84static void
a94434b6 85route_match_metric_free (void *rule)
86{
87 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
88}
89
90/* Route map commands for metric matching. */
6ac29a51 91static struct route_map_rule_cmd route_match_metric_cmd =
a94434b6 92{
93 "metric",
94 route_match_metric,
95 route_match_metric_compile,
96 route_match_metric_free
97};
6b0655a2 98
718e3744 99/* `match interface IFNAME' */
a94434b6 100/* Match function return 1 if match is success else return zero. */
6ac29a51 101static route_map_result_t
718e3744 102route_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
a94434b6 109 if (type == RMAP_RIPNG)
718e3744 110 {
111 ifname = rule;
1306c09a 112 ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
718e3744 113
114 if (!ifp)
a94434b6 115 return RMAP_NOMATCH;
718e3744 116
117 rinfo = object;
118
119 if (rinfo->ifindex == ifp->ifindex)
a94434b6 120 return RMAP_MATCH;
718e3744 121 else
a94434b6 122 return RMAP_NOMATCH;
718e3744 123 }
a94434b6 124 return RMAP_NOMATCH;
718e3744 125}
126
a94434b6 127/* Route map `match interface' match statement. `arg' is IFNAME value */
6ac29a51 128static void *
98b718a9 129route_match_interface_compile (const char *arg)
718e3744 130{
131 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
132}
133
6ac29a51 134static void
718e3744 135route_match_interface_free (void *rule)
136{
137 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
138}
139
6ac29a51 140static struct route_map_rule_cmd route_match_interface_cmd =
718e3744 141{
142 "interface",
143 route_match_interface,
144 route_match_interface_compile,
145 route_match_interface_free
146};
a94434b6 147
148/* `match tag TAG' */
149/* Match function return 1 if match is success else return zero. */
6ac29a51 150static route_map_result_t
a94434b6 151route_match_tag (void *rule, struct prefix *prefix,
152 route_map_object_t type, void *object)
718e3744 153{
dc9ffce8 154 route_tag_t *tag;
a94434b6 155 struct ripng_info *rinfo;
dc9ffce8 156 route_tag_t rinfo_tag;
718e3744 157
a94434b6 158 if (type == RMAP_RIPNG)
159 {
160 tag = rule;
161 rinfo = object;
162
163 /* The information stored by rinfo is host ordered. */
dc9ffce8
CF
164 rinfo_tag = rinfo->tag;
165 if (rinfo_tag == *tag)
a94434b6 166 return RMAP_MATCH;
167 else
168 return RMAP_NOMATCH;
169 }
170 return RMAP_NOMATCH;
171}
172
6ac29a51 173static struct route_map_rule_cmd route_match_tag_cmd =
a94434b6 174{
175 "tag",
176 route_match_tag,
dc9ffce8
CF
177 route_map_rule_tag_compile,
178 route_map_rule_tag_free,
718e3744 179};
6b0655a2 180
a94434b6 181/* `set metric METRIC' */
718e3744 182
a94434b6 183/* Set metric to attribute. */
6ac29a51 184static route_map_result_t
718e3744 185route_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)
a94434b6 197 rinfo->metric_out += mod->metric;
718e3744 198 else if (mod->type == metric_decrement)
a94434b6 199 rinfo->metric_out-= mod->metric;
718e3744 200 else if (mod->type == metric_absolute)
a94434b6 201 rinfo->metric_out = mod->metric;
718e3744 202
a94434b6 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;
718e3744 207
208 rinfo->metric_set = 1;
209 }
210 return RMAP_OKAY;
211}
212
a94434b6 213/* set metric compilation. */
6ac29a51 214static void *
98b718a9 215route_set_metric_compile (const char *arg)
718e3744 216{
217 int len;
98b718a9 218 const char *pnt;
718e3744 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;
73ffb25b 253 /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
254 /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
255 if (metric < 0)
718e3744 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
a94434b6 266/* Free route map's compiled `set metric' value. */
6ac29a51 267static void
718e3744 268route_set_metric_free (void *rule)
269{
270 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
271}
272
6ac29a51 273static struct route_map_rule_cmd route_set_metric_cmd =
718e3744 274{
275 "metric",
276 route_set_metric,
277 route_set_metric_compile,
278 route_set_metric_free,
279};
a94434b6 280
281/* `set ipv6 next-hop local IP_ADDRESS' */
282
283/* Set nexthop to object. ojbect must be pointer to struct attr. */
6ac29a51 284static route_map_result_t
a94434b6 285route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
286 route_map_object_t type, void *object)
718e3744 287{
a94434b6 288 struct in6_addr *address;
289 struct ripng_info *rinfo;
718e3744 290
a94434b6 291 if(type == RMAP_RIPNG)
718e3744 292 {
a94434b6 293 /* Fetch routemap's rule information. */
294 address = rule;
295 rinfo = object;
296
297 /* Set next hop value. */
298 rinfo->nexthop_out = *address;
718e3744 299 }
a94434b6 300
301 return RMAP_OKAY;
718e3744 302}
303
a94434b6 304/* Route map `ipv6 nexthop local' compile function. Given string is converted
305 to struct in6_addr structure. */
6ac29a51 306static void *
98b718a9 307route_set_ipv6_nexthop_local_compile (const char *arg)
718e3744 308{
309 int ret;
a94434b6 310 struct in6_addr *address;
718e3744 311
7a559cbe 312 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
a94434b6 313
314 ret = inet_pton (AF_INET6, arg, address);
315
316 if (ret == 0)
718e3744 317 {
a94434b6 318 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
319 return NULL;
718e3744 320 }
a94434b6 321
322 return address;
718e3744 323}
324
a94434b6 325/* Free route map's compiled `ipv6 nexthop local' value. */
6ac29a51 326static void
a94434b6 327route_set_ipv6_nexthop_local_free (void *rule)
718e3744 328{
a94434b6 329 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
330}
718e3744 331
a94434b6 332/* Route map commands for ipv6 nexthop local set. */
6ac29a51 333static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
a94434b6 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. */
6ac29a51 344static route_map_result_t
a94434b6 345route_set_tag (void *rule, struct prefix *prefix,
346 route_map_object_t type, void *object)
347{
dc9ffce8 348 route_tag_t *tag;
a94434b6 349 struct ripng_info *rinfo;
350
351 if(type == RMAP_RIPNG)
718e3744 352 {
a94434b6 353 /* Fetch routemap's rule information. */
354 tag = rule;
355 rinfo = object;
356
357 /* Set next hop value. */
358 rinfo->tag_out = *tag;
718e3744 359 }
a94434b6 360
361 return RMAP_OKAY;
718e3744 362}
363
a94434b6 364/* Route map commands for tag set. */
6ac29a51 365static struct route_map_rule_cmd route_set_tag_cmd =
a94434b6 366{
367 "tag",
368 route_set_tag,
dc9ffce8
CF
369 route_map_rule_tag_compile,
370 route_map_rule_tag_free
a94434b6 371};
6b0655a2 372
a94434b6 373#define MATCH_STR "Match values from routing table\n"
374#define SET_STR "Set values in destination routing protocol\n"
375
a94434b6 376void
377ripng_route_map_reset ()
378{
379 /* XXX ??? */
380 ;
381}
382
718e3744 383void
384ripng_route_map_init ()
385{
386 route_map_init ();
718e3744 387
82f97584
DW
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
a94434b6 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);
718e3744 409 route_map_install_set (&route_set_metric_cmd);
a94434b6 410 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
411 route_map_install_set (&route_set_tag_cmd);
718e3744 412}