2 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
3 * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #include "sockunion.h" /* for inet_aton () */
35 #include "ripd/ripd.h"
37 struct rip_metric_modifier
49 /* Hook function for updating route_map assignment. */
52 rip_route_map_update (const char *notused
)
58 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
60 if (rip
->route_map
[i
].name
)
61 rip
->route_map
[i
].map
=
62 route_map_lookup_by_name (rip
->route_map
[i
].name
);
67 /* `match metric METRIC' */
68 /* Match function return 1 if match is success else return zero. */
69 static route_map_result_t
70 route_match_metric (void *rule
, struct prefix
*prefix
,
71 route_map_object_t type
, void *object
)
75 struct rip_info
*rinfo
;
82 /* If external metric is available, the route-map should
83 work on this one (for redistribute purpose) */
84 check
= (rinfo
->external_metric
) ? rinfo
->external_metric
:
94 /* Route map `match metric' match statement. `arg' is METRIC value */
96 route_match_metric_compile (const char *arg
)
100 metric
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
101 *metric
= atoi (arg
);
106 XFREE (MTYPE_ROUTE_MAP_COMPILED
, metric
);
110 /* Free route map's compiled `match metric' value. */
112 route_match_metric_free (void *rule
)
114 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
117 /* Route map commands for metric matching. */
118 struct route_map_rule_cmd route_match_metric_cmd
=
122 route_match_metric_compile
,
123 route_match_metric_free
126 /* `match interface IFNAME' */
127 /* Match function return 1 if match is success else return zero. */
128 static route_map_result_t
129 route_match_interface (void *rule
, struct prefix
*prefix
,
130 route_map_object_t type
, void *object
)
132 struct rip_info
*rinfo
;
133 struct interface
*ifp
;
136 if (type
== RMAP_RIP
)
139 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
146 if (rinfo
->ifindex_out
== ifp
->ifindex
|| rinfo
->ifindex
== ifp
->ifindex
)
154 /* Route map `match interface' match statement. `arg' is IFNAME value */
155 /* XXX I don`t know if I need to check does interface exist? */
157 route_match_interface_compile (const char *arg
)
159 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
162 /* Free route map's compiled `match interface' value. */
164 route_match_interface_free (void *rule
)
166 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
169 /* Route map commands for interface matching. */
170 struct route_map_rule_cmd route_match_interface_cmd
=
173 route_match_interface
,
174 route_match_interface_compile
,
175 route_match_interface_free
178 /* `match ip next-hop IP_ACCESS_LIST' */
180 /* Match function return 1 if match is success else return zero. */
181 static route_map_result_t
182 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
183 route_map_object_t type
, void *object
)
185 struct access_list
*alist
;
186 struct rip_info
*rinfo
;
187 struct prefix_ipv4 p
;
189 if (type
== RMAP_RIP
)
193 p
.prefix
= (rinfo
->nexthop
.s_addr
) ? rinfo
->nexthop
: rinfo
->from
;
194 p
.prefixlen
= IPV4_MAX_BITLEN
;
196 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
200 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
201 RMAP_NOMATCH
: RMAP_MATCH
);
206 /* Route map `ip next-hop' match statement. `arg' should be
209 route_match_ip_next_hop_compile (const char *arg
)
211 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
214 /* Free route map's compiled `. */
216 route_match_ip_next_hop_free (void *rule
)
218 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
221 /* Route map commands for ip next-hop matching. */
222 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
225 route_match_ip_next_hop
,
226 route_match_ip_next_hop_compile
,
227 route_match_ip_next_hop_free
230 /* `match ip next-hop prefix-list PREFIX_LIST' */
232 static route_map_result_t
233 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
234 route_map_object_t type
, void *object
)
236 struct prefix_list
*plist
;
237 struct rip_info
*rinfo
;
238 struct prefix_ipv4 p
;
240 if (type
== RMAP_RIP
)
244 p
.prefix
= (rinfo
->nexthop
.s_addr
) ? rinfo
->nexthop
: rinfo
->from
;
245 p
.prefixlen
= IPV4_MAX_BITLEN
;
247 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
251 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
252 RMAP_NOMATCH
: RMAP_MATCH
);
258 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
260 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
264 route_match_ip_next_hop_prefix_list_free (void *rule
)
266 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
269 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
271 "ip next-hop prefix-list",
272 route_match_ip_next_hop_prefix_list
,
273 route_match_ip_next_hop_prefix_list_compile
,
274 route_match_ip_next_hop_prefix_list_free
277 /* `match ip address IP_ACCESS_LIST' */
279 /* Match function should return 1 if match is success else return
281 static route_map_result_t
282 route_match_ip_address (void *rule
, struct prefix
*prefix
,
283 route_map_object_t type
, void *object
)
285 struct access_list
*alist
;
287 if (type
== RMAP_RIP
)
289 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
293 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
294 RMAP_NOMATCH
: RMAP_MATCH
);
299 /* Route map `ip address' match statement. `arg' should be
302 route_match_ip_address_compile (const char *arg
)
304 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
307 /* Free route map's compiled `ip address' value. */
309 route_match_ip_address_free (void *rule
)
311 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
314 /* Route map commands for ip address matching. */
315 static struct route_map_rule_cmd route_match_ip_address_cmd
=
318 route_match_ip_address
,
319 route_match_ip_address_compile
,
320 route_match_ip_address_free
323 /* `match ip address prefix-list PREFIX_LIST' */
325 static route_map_result_t
326 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
327 route_map_object_t type
, void *object
)
329 struct prefix_list
*plist
;
331 if (type
== RMAP_RIP
)
333 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
337 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
338 RMAP_NOMATCH
: RMAP_MATCH
);
344 route_match_ip_address_prefix_list_compile (const char *arg
)
346 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
350 route_match_ip_address_prefix_list_free (void *rule
)
352 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
355 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
357 "ip address prefix-list",
358 route_match_ip_address_prefix_list
,
359 route_match_ip_address_prefix_list_compile
,
360 route_match_ip_address_prefix_list_free
363 /* `match tag TAG' */
364 /* Match function return 1 if match is success else return zero. */
365 static route_map_result_t
366 route_match_tag (void *rule
, struct prefix
*prefix
,
367 route_map_object_t type
, void *object
)
370 struct rip_info
*rinfo
;
371 route_tag_t rinfo_tag
;
373 if (type
== RMAP_RIP
)
378 /* The information stored by rinfo is host ordered. */
379 rinfo_tag
= rinfo
->tag
;
380 if (rinfo_tag
== *tag
)
388 /* Route map commands for tag matching. */
389 static struct route_map_rule_cmd route_match_tag_cmd
=
393 route_map_rule_tag_compile
,
394 route_map_rule_tag_free
,
397 /* `set metric METRIC' */
399 /* Set metric to attribute. */
400 static route_map_result_t
401 route_set_metric (void *rule
, struct prefix
*prefix
,
402 route_map_object_t type
, void *object
)
404 if (type
== RMAP_RIP
)
406 struct rip_metric_modifier
*mod
;
407 struct rip_info
*rinfo
;
412 if (mod
->type
== metric_increment
)
413 rinfo
->metric_out
+= mod
->metric
;
414 else if (mod
->type
== metric_decrement
)
415 rinfo
->metric_out
-= mod
->metric
;
416 else if (mod
->type
== metric_absolute
)
417 rinfo
->metric_out
= mod
->metric
;
419 if ((signed int)rinfo
->metric_out
< 1)
420 rinfo
->metric_out
= 1;
421 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
422 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
424 rinfo
->metric_set
= 1;
429 /* set metric compilation. */
431 route_set_metric_compile (const char *arg
)
438 struct rip_metric_modifier
*mod
;
446 /* Examine first character. */
449 type
= metric_increment
;
452 else if (arg
[0] == '-')
454 type
= metric_decrement
;
458 type
= metric_absolute
;
460 /* Check beginning with digit string. */
461 if (*pnt
< '0' || *pnt
> '9')
464 /* Convert string to integer. */
465 metric
= strtol (pnt
, &endptr
, 10);
467 if (metric
== LONG_MAX
|| *endptr
!= '\0')
469 if (metric
< 0 || metric
> RIP_METRIC_INFINITY
)
472 mod
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
473 sizeof (struct rip_metric_modifier
));
475 mod
->metric
= metric
;
480 /* Free route map's compiled `set metric' value. */
482 route_set_metric_free (void *rule
)
484 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
487 /* Set metric rule structure. */
488 static struct route_map_rule_cmd route_set_metric_cmd
=
492 route_set_metric_compile
,
493 route_set_metric_free
,
496 /* `set ip next-hop IP_ADDRESS' */
498 /* Set nexthop to object. ojbect must be pointer to struct attr. */
499 static route_map_result_t
500 route_set_ip_nexthop (void *rule
, struct prefix
*prefix
,
501 route_map_object_t type
, void *object
)
503 struct in_addr
*address
;
504 struct rip_info
*rinfo
;
508 /* Fetch routemap's rule information. */
512 /* Set next hop value. */
513 rinfo
->nexthop_out
= *address
;
519 /* Route map `ip nexthop' compile function. Given string is converted
520 to struct in_addr structure. */
522 route_set_ip_nexthop_compile (const char *arg
)
525 struct in_addr
*address
;
527 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
529 ret
= inet_aton (arg
, address
);
533 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
540 /* Free route map's compiled `ip nexthop' value. */
542 route_set_ip_nexthop_free (void *rule
)
544 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
547 /* Route map commands for ip nexthop set. */
548 static struct route_map_rule_cmd route_set_ip_nexthop_cmd
=
551 route_set_ip_nexthop
,
552 route_set_ip_nexthop_compile
,
553 route_set_ip_nexthop_free
558 /* Set tag to object. ojbect must be pointer to struct attr. */
559 static route_map_result_t
560 route_set_tag (void *rule
, struct prefix
*prefix
,
561 route_map_object_t type
, void *object
)
564 struct rip_info
*rinfo
;
568 /* Fetch routemap's rule information. */
572 /* Set next hop value. */
573 rinfo
->tag_out
= *tag
;
579 /* Route map commands for tag set. */
580 static struct route_map_rule_cmd route_set_tag_cmd
=
584 route_map_rule_tag_compile
,
585 route_map_rule_tag_free
588 #define MATCH_STR "Match values from routing table\n"
589 #define SET_STR "Set values in destination routing protocol\n"
592 rip_route_map_reset ()
599 rip_route_map_init ()
603 route_map_add_hook (rip_route_map_update
);
604 route_map_delete_hook (rip_route_map_update
);
606 route_map_match_interface_hook (generic_match_add
);
607 route_map_no_match_interface_hook (generic_match_delete
);
609 route_map_match_ip_address_hook (generic_match_add
);
610 route_map_no_match_ip_address_hook (generic_match_delete
);
612 route_map_match_ip_address_prefix_list_hook (generic_match_add
);
613 route_map_no_match_ip_address_prefix_list_hook (generic_match_delete
);
615 route_map_match_ip_next_hop_hook (generic_match_add
);
616 route_map_no_match_ip_next_hop_hook (generic_match_delete
);
618 route_map_match_ip_next_hop_prefix_list_hook (generic_match_add
);
619 route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete
);
621 route_map_match_metric_hook (generic_match_add
);
622 route_map_no_match_metric_hook (generic_match_delete
);
624 route_map_match_tag_hook (generic_match_add
);
625 route_map_no_match_tag_hook (generic_match_delete
);
627 route_map_set_ip_nexthop_hook (generic_set_add
);
628 route_map_no_set_ip_nexthop_hook (generic_set_delete
);
630 route_map_set_metric_hook (generic_set_add
);
631 route_map_no_set_metric_hook (generic_set_delete
);
633 route_map_set_tag_hook (generic_set_add
);
634 route_map_no_set_tag_hook (generic_set_delete
);
636 route_map_install_match (&route_match_metric_cmd
);
637 route_map_install_match (&route_match_interface_cmd
);
638 route_map_install_match (&route_match_ip_next_hop_cmd
);
639 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
640 route_map_install_match (&route_match_ip_address_cmd
);
641 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
642 route_map_install_match (&route_match_tag_cmd
);
644 route_map_install_set (&route_set_metric_cmd
);
645 route_map_install_set (&route_set_ip_nexthop_cmd
);
646 route_map_install_set (&route_set_tag_cmd
);