2 * Copyright (C) 1999 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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
30 #include "sockunion.h"
32 #include "ripngd/ripngd.h"
34 struct rip_metric_modifier
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
)
53 struct ripng_info
*rinfo
;
55 if (type
== RMAP_RIPNG
)
60 if (rinfo
->metric
== *metric
)
68 /* Route map `match metric' match statement. `arg' is METRIC value */
70 route_match_metric_compile (const char *arg
)
74 metric
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
80 XFREE (MTYPE_ROUTE_MAP_COMPILED
, metric
);
84 /* Free route map's compiled `match metric' value. */
86 route_match_metric_free (void *rule
)
88 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
91 /* Route map commands for metric matching. */
92 static struct route_map_rule_cmd route_match_metric_cmd
=
96 route_match_metric_compile
,
97 route_match_metric_free
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
)
106 struct ripng_info
*rinfo
;
107 struct interface
*ifp
;
110 if (type
== RMAP_RIPNG
)
113 ifp
= if_lookup_by_name(ifname
);
120 if (rinfo
->ifindex
== ifp
->ifindex
)
128 /* Route map `match interface' match statement. `arg' is IFNAME value */
130 route_match_interface_compile (const char *arg
)
132 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
136 route_match_interface_free (void *rule
)
138 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
141 static struct route_map_rule_cmd route_match_interface_cmd
=
144 route_match_interface
,
145 route_match_interface_compile
,
146 route_match_interface_free
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
)
156 struct ripng_info
*rinfo
;
157 route_tag_t rinfo_tag
;
159 if (type
== RMAP_RIPNG
)
164 /* The information stored by rinfo is host ordered. */
165 rinfo_tag
= rinfo
->tag
;
166 if (rinfo_tag
== *tag
)
174 static struct route_map_rule_cmd route_match_tag_cmd
=
178 route_map_rule_tag_compile
,
179 route_map_rule_tag_free
,
182 /* `set metric METRIC' */
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
)
189 if (type
== RMAP_RIPNG
)
191 struct rip_metric_modifier
*mod
;
192 struct ripng_info
*rinfo
;
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
;
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
;
209 rinfo
->metric_set
= 1;
214 /* set metric compilation. */
216 route_set_metric_compile (const char *arg
)
223 struct rip_metric_modifier
*mod
;
231 /* Examine first character. */
234 type
= metric_increment
;
237 else if (arg
[0] == '-')
239 type
= metric_decrement
;
243 type
= metric_absolute
;
245 /* Check beginning with digit string. */
246 if (*pnt
< '0' || *pnt
> '9')
249 /* Convert string to integer. */
250 metric
= strtol (pnt
, &endptr
, 10);
252 if (metric
== LONG_MAX
|| *endptr
!= '\0')
254 /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
255 /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
259 mod
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
260 sizeof (struct rip_metric_modifier
));
262 mod
->metric
= metric
;
267 /* Free route map's compiled `set metric' value. */
269 route_set_metric_free (void *rule
)
271 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
274 static struct route_map_rule_cmd route_set_metric_cmd
=
278 route_set_metric_compile
,
279 route_set_metric_free
,
282 /* `set ipv6 next-hop local IP_ADDRESS' */
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
)
289 struct in6_addr
*address
;
290 struct ripng_info
*rinfo
;
292 if(type
== RMAP_RIPNG
)
294 /* Fetch routemap's rule information. */
298 /* Set next hop value. */
299 rinfo
->nexthop_out
= *address
;
305 /* Route map `ipv6 nexthop local' compile function. Given string is converted
306 to struct in6_addr structure. */
308 route_set_ipv6_nexthop_local_compile (const char *arg
)
311 struct in6_addr
*address
;
313 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
315 ret
= inet_pton (AF_INET6
, arg
, address
);
319 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
326 /* Free route map's compiled `ipv6 nexthop local' value. */
328 route_set_ipv6_nexthop_local_free (void *rule
)
330 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
333 /* Route map commands for ipv6 nexthop local set. */
334 static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
=
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
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
)
350 struct ripng_info
*rinfo
;
352 if(type
== RMAP_RIPNG
)
354 /* Fetch routemap's rule information. */
358 /* Set next hop value. */
359 rinfo
->tag_out
= *tag
;
365 /* Route map commands for tag set. */
366 static struct route_map_rule_cmd route_set_tag_cmd
=
370 route_map_rule_tag_compile
,
371 route_map_rule_tag_free
374 #define MATCH_STR "Match values from routing table\n"
375 #define SET_STR "Set values in destination routing protocol\n"
378 ripng_route_map_reset ()
385 ripng_route_map_init ()
389 route_map_match_interface_hook (generic_match_add
);
390 route_map_no_match_interface_hook (generic_match_delete
);
392 route_map_match_metric_hook (generic_match_add
);
393 route_map_no_match_metric_hook (generic_match_delete
);
395 route_map_match_tag_hook (generic_match_add
);
396 route_map_no_match_tag_hook (generic_match_delete
);
398 route_map_set_ipv6_nexthop_local_hook (generic_set_add
);
399 route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete
);
401 route_map_set_metric_hook (generic_set_add
);
402 route_map_no_set_metric_hook (generic_set_delete
);
404 route_map_set_tag_hook (generic_set_add
);
405 route_map_no_set_tag_hook (generic_set_delete
);
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
);