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
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
32 #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
);
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
;
372 if (type
== RMAP_RIP
)
377 /* The information stored by rinfo is host ordered. */
378 if (rinfo
->tag
== *tag
)
386 /* Route map `match tag' match statement. `arg' is TAG value */
388 route_match_tag_compile (const char *arg
)
393 /* tag value shoud be integer. */
394 if (! all_digit (arg
))
401 tag
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_short
));
411 /* Free route map's compiled `match tag' value. */
413 route_match_tag_free (void *rule
)
415 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
418 /* Route map commands for tag matching. */
419 struct route_map_rule_cmd route_match_tag_cmd
=
423 route_match_tag_compile
,
427 /* `set metric METRIC' */
429 /* Set metric to attribute. */
430 static route_map_result_t
431 route_set_metric (void *rule
, struct prefix
*prefix
,
432 route_map_object_t type
, void *object
)
434 if (type
== RMAP_RIP
)
436 struct rip_metric_modifier
*mod
;
437 struct rip_info
*rinfo
;
442 if (mod
->type
== metric_increment
)
443 rinfo
->metric_out
+= mod
->metric
;
444 else if (mod
->type
== metric_decrement
)
445 rinfo
->metric_out
-= mod
->metric
;
446 else if (mod
->type
== metric_absolute
)
447 rinfo
->metric_out
= mod
->metric
;
449 if ((signed int)rinfo
->metric_out
< 1)
450 rinfo
->metric_out
= 1;
451 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
452 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
454 rinfo
->metric_set
= 1;
459 /* set metric compilation. */
461 route_set_metric_compile (const char *arg
)
468 struct rip_metric_modifier
*mod
;
476 /* Examine first character. */
479 type
= metric_increment
;
482 else if (arg
[0] == '-')
484 type
= metric_decrement
;
488 type
= metric_absolute
;
490 /* Check beginning with digit string. */
491 if (*pnt
< '0' || *pnt
> '9')
494 /* Convert string to integer. */
495 metric
= strtol (pnt
, &endptr
, 10);
497 if (metric
== LONG_MAX
|| *endptr
!= '\0')
499 if (metric
< 0 || metric
> RIP_METRIC_INFINITY
)
502 mod
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
503 sizeof (struct rip_metric_modifier
));
505 mod
->metric
= metric
;
510 /* Free route map's compiled `set metric' value. */
512 route_set_metric_free (void *rule
)
514 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
517 /* Set metric rule structure. */
518 static struct route_map_rule_cmd route_set_metric_cmd
=
522 route_set_metric_compile
,
523 route_set_metric_free
,
526 /* `set ip next-hop IP_ADDRESS' */
528 /* Set nexthop to object. ojbect must be pointer to struct attr. */
529 static route_map_result_t
530 route_set_ip_nexthop (void *rule
, struct prefix
*prefix
,
531 route_map_object_t type
, void *object
)
533 struct in_addr
*address
;
534 struct rip_info
*rinfo
;
538 /* Fetch routemap's rule information. */
542 /* Set next hop value. */
543 rinfo
->nexthop_out
= *address
;
549 /* Route map `ip nexthop' compile function. Given string is converted
550 to struct in_addr structure. */
552 route_set_ip_nexthop_compile (const char *arg
)
555 struct in_addr
*address
;
557 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
559 ret
= inet_aton (arg
, address
);
563 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
570 /* Free route map's compiled `ip nexthop' value. */
572 route_set_ip_nexthop_free (void *rule
)
574 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
577 /* Route map commands for ip nexthop set. */
578 static struct route_map_rule_cmd route_set_ip_nexthop_cmd
=
581 route_set_ip_nexthop
,
582 route_set_ip_nexthop_compile
,
583 route_set_ip_nexthop_free
588 /* Set tag to object. ojbect must be pointer to struct attr. */
589 static route_map_result_t
590 route_set_tag (void *rule
, struct prefix
*prefix
,
591 route_map_object_t type
, void *object
)
594 struct rip_info
*rinfo
;
598 /* Fetch routemap's rule information. */
602 /* Set next hop value. */
603 rinfo
->tag_out
= *tag
;
609 /* Route map `tag' compile function. Given string is converted
612 route_set_tag_compile (const char *arg
)
616 tag
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_short
));
622 /* Free route map's compiled `ip nexthop' value. */
624 route_set_tag_free (void *rule
)
626 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
629 /* Route map commands for tag set. */
630 static struct route_map_rule_cmd route_set_tag_cmd
=
634 route_set_tag_compile
,
638 #define MATCH_STR "Match values from routing table\n"
639 #define SET_STR "Set values in destination routing protocol\n"
642 rip_route_map_reset ()
649 rip_route_map_init ()
652 route_map_init_vty ();
653 route_map_add_hook (rip_route_map_update
);
654 route_map_delete_hook (rip_route_map_update
);
656 route_map_match_interface_hook (generic_match_add
);
657 route_map_no_match_interface_hook (generic_match_delete
);
659 route_map_match_ip_address_hook (generic_match_add
);
660 route_map_no_match_ip_address_hook (generic_match_delete
);
662 route_map_match_ip_address_prefix_list_hook (generic_match_add
);
663 route_map_no_match_ip_address_prefix_list_hook (generic_match_delete
);
665 route_map_match_ip_next_hop_hook (generic_match_add
);
666 route_map_no_match_ip_next_hop_hook (generic_match_delete
);
668 route_map_match_ip_next_hop_prefix_list_hook (generic_match_add
);
669 route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete
);
671 route_map_match_metric_hook (generic_match_add
);
672 route_map_no_match_metric_hook (generic_match_delete
);
674 route_map_match_tag_hook (generic_match_add
);
675 route_map_no_match_tag_hook (generic_match_delete
);
677 route_map_set_ip_nexthop_hook (generic_set_add
);
678 route_map_no_set_ip_nexthop_hook (generic_set_delete
);
680 route_map_set_metric_hook (generic_set_add
);
681 route_map_no_set_metric_hook (generic_set_delete
);
683 route_map_set_tag_hook (generic_set_add
);
684 route_map_no_set_tag_hook (generic_set_delete
);
686 route_map_install_match (&route_match_metric_cmd
);
687 route_map_install_match (&route_match_interface_cmd
);
688 route_map_install_match (&route_match_ip_next_hop_cmd
);
689 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
690 route_map_install_match (&route_match_ip_address_cmd
);
691 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
692 route_map_install_match (&route_match_tag_cmd
);
694 route_map_install_set (&route_set_metric_cmd
);
695 route_map_install_set (&route_set_ip_nexthop_cmd
);
696 route_map_install_set (&route_set_tag_cmd
);