2 * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
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" /* for inet_aton () */
33 #include "ripd/ripd.h"
35 /* Add rip route map rule. */
37 rip_route_match_add (struct vty
*vty
, struct route_map_index
*index
,
38 char *command
, char *arg
)
42 ret
= route_map_add_match (index
, command
, arg
);
47 case RMAP_RULE_MISSING
:
48 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
51 case RMAP_COMPILE_ERROR
:
52 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
60 /* Delete rip route map rule. */
62 rip_route_match_delete (struct vty
*vty
, struct route_map_index
*index
,
63 char *command
, char *arg
)
67 ret
= route_map_delete_match (index
, command
, arg
);
72 case RMAP_RULE_MISSING
:
73 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
76 case RMAP_COMPILE_ERROR
:
77 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
85 /* Add rip route map rule. */
87 rip_route_set_add (struct vty
*vty
, struct route_map_index
*index
,
88 char *command
, char *arg
)
92 ret
= route_map_add_set (index
, command
, arg
);
97 case RMAP_RULE_MISSING
:
98 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
101 case RMAP_COMPILE_ERROR
:
102 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
110 /* Delete rip route map rule. */
112 rip_route_set_delete (struct vty
*vty
, struct route_map_index
*index
,
113 char *command
, char *arg
)
117 ret
= route_map_delete_set (index
, command
, arg
);
122 case RMAP_RULE_MISSING
:
123 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
126 case RMAP_COMPILE_ERROR
:
127 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
135 /* Hook function for updating route_map assignment. */
137 rip_route_map_update ()
143 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
145 if (rip
->route_map
[i
].name
)
146 rip
->route_map
[i
].map
=
147 route_map_lookup_by_name (rip
->route_map
[i
].name
);
152 /* `match metric METRIC' */
153 /* Match function return 1 if match is success else return zero. */
155 route_match_metric (void *rule
, struct prefix
*prefix
,
156 route_map_object_t type
, void *object
)
159 struct rip_info
*rinfo
;
161 if (type
== RMAP_RIP
)
166 if (rinfo
->metric
== *metric
)
174 /* Route map `match metric' match statement. `arg' is METRIC value */
176 route_match_metric_compile (char *arg
)
180 metric
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
181 *metric
= atoi (arg
);
186 XFREE (MTYPE_ROUTE_MAP_COMPILED
, metric
);
190 /* Free route map's compiled `match metric' value. */
192 route_match_metric_free (void *rule
)
194 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
197 /* Route map commands for metric matching. */
198 struct route_map_rule_cmd route_match_metric_cmd
=
202 route_match_metric_compile
,
203 route_match_metric_free
206 /* `match interface IFNAME' */
207 /* Match function return 1 if match is success else return zero. */
209 route_match_interface (void *rule
, struct prefix
*prefix
,
210 route_map_object_t type
, void *object
)
212 struct rip_info
*rinfo
;
213 struct interface
*ifp
;
216 if (type
== RMAP_RIP
)
219 ifp
= if_lookup_by_name(ifname
);
226 if (rinfo
->ifindex_out
== ifp
->ifindex
)
234 /* Route map `match interface' match statement. `arg' is IFNAME value */
235 /* XXX I don`t know if I need to check does interface exist? */
237 route_match_interface_compile (char *arg
)
239 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
242 /* Free route map's compiled `match interface' value. */
244 route_match_interface_free (void *rule
)
246 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
249 /* Route map commands for interface matching. */
250 struct route_map_rule_cmd route_match_interface_cmd
=
253 route_match_interface
,
254 route_match_interface_compile
,
255 route_match_interface_free
258 /* `match ip next-hop IP_ACCESS_LIST' */
260 /* Match function return 1 if match is success else return zero. */
262 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
263 route_map_object_t type
, void *object
)
265 struct access_list
*alist
;
266 struct rip_info
*rinfo
;
267 struct prefix_ipv4 p
;
269 if (type
== RMAP_RIP
)
273 p
.prefix
= rinfo
->nexthop
;
274 p
.prefixlen
= IPV4_MAX_BITLEN
;
276 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
280 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
281 RMAP_NOMATCH
: RMAP_MATCH
);
286 /* Route map `ip next-hop' match statement. `arg' should be
289 route_match_ip_next_hop_compile (char *arg
)
291 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
294 /* Free route map's compiled `. */
296 route_match_ip_next_hop_free (void *rule
)
298 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
301 /* Route map commands for ip next-hop matching. */
302 struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
305 route_match_ip_next_hop
,
306 route_match_ip_next_hop_compile
,
307 route_match_ip_next_hop_free
310 /* `match ip next-hop prefix-list PREFIX_LIST' */
313 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
314 route_map_object_t type
, void *object
)
316 struct prefix_list
*plist
;
317 struct rip_info
*rinfo
;
318 struct prefix_ipv4 p
;
320 if (type
== RMAP_RIP
)
324 p
.prefix
= rinfo
->nexthop
;
325 p
.prefixlen
= IPV4_MAX_BITLEN
;
327 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
331 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
332 RMAP_NOMATCH
: RMAP_MATCH
);
338 route_match_ip_next_hop_prefix_list_compile (char *arg
)
340 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
344 route_match_ip_next_hop_prefix_list_free (void *rule
)
346 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
349 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
351 "ip next-hop prefix-list",
352 route_match_ip_next_hop_prefix_list
,
353 route_match_ip_next_hop_prefix_list_compile
,
354 route_match_ip_next_hop_prefix_list_free
357 /* `match ip address IP_ACCESS_LIST' */
359 /* Match function should return 1 if match is success else return
362 route_match_ip_address (void *rule
, struct prefix
*prefix
,
363 route_map_object_t type
, void *object
)
365 struct access_list
*alist
;
367 if (type
== RMAP_RIP
)
369 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
373 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
374 RMAP_NOMATCH
: RMAP_MATCH
);
379 /* Route map `ip address' match statement. `arg' should be
382 route_match_ip_address_compile (char *arg
)
384 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
387 /* Free route map's compiled `ip address' value. */
389 route_match_ip_address_free (void *rule
)
391 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
394 /* Route map commands for ip address matching. */
395 struct route_map_rule_cmd route_match_ip_address_cmd
=
398 route_match_ip_address
,
399 route_match_ip_address_compile
,
400 route_match_ip_address_free
403 /* `match ip address prefix-list PREFIX_LIST' */
406 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
407 route_map_object_t type
, void *object
)
409 struct prefix_list
*plist
;
411 if (type
== RMAP_RIP
)
413 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
417 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
418 RMAP_NOMATCH
: RMAP_MATCH
);
424 route_match_ip_address_prefix_list_compile (char *arg
)
426 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
430 route_match_ip_address_prefix_list_free (void *rule
)
432 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
435 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
437 "ip address prefix-list",
438 route_match_ip_address_prefix_list
,
439 route_match_ip_address_prefix_list_compile
,
440 route_match_ip_address_prefix_list_free
443 /* `set metric METRIC' */
445 /* Set metric to attribute. */
447 route_set_metric (void *rule
, struct prefix
*prefix
,
448 route_map_object_t type
, void *object
)
451 struct rip_info
*rinfo
;
453 if (type
== RMAP_RIP
)
455 /* Fetch routemap's rule information. */
459 /* Set metric out value. */
460 rinfo
->metric_out
= *metric
;
461 rinfo
->metric_set
= 1;
466 /* set metric compilation. */
468 route_set_metric_compile (char *arg
)
472 metric
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
473 *metric
= atoi (arg
);
478 /* Free route map's compiled `set metric' value. */
480 route_set_metric_free (void *rule
)
482 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
485 /* Set metric rule structure. */
486 struct route_map_rule_cmd route_set_metric_cmd
=
490 route_set_metric_compile
,
491 route_set_metric_free
,
494 /* `set ip next-hop IP_ADDRESS' */
496 /* Set nexthop to object. ojbect must be pointer to struct attr. */
498 route_set_ip_nexthop (void *rule
, struct prefix
*prefix
,
499 route_map_object_t type
, void *object
)
501 struct in_addr
*address
;
502 struct rip_info
*rinfo
;
506 /* Fetch routemap's rule information. */
510 /* Set next hop value. */
511 rinfo
->nexthop_out
= *address
;
517 /* Route map `ip nexthop' compile function. Given string is converted
518 to struct in_addr structure. */
520 route_set_ip_nexthop_compile (char *arg
)
523 struct in_addr
*address
;
525 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
527 ret
= inet_aton (arg
, address
);
531 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
538 /* Free route map's compiled `ip nexthop' value. */
540 route_set_ip_nexthop_free (void *rule
)
542 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
545 /* Route map commands for ip nexthop set. */
546 struct route_map_rule_cmd route_set_ip_nexthop_cmd
=
549 route_set_ip_nexthop
,
550 route_set_ip_nexthop_compile
,
551 route_set_ip_nexthop_free
554 #define MATCH_STR "Match values from routing table\n"
555 #define SET_STR "Set values in destination routing protocol\n"
559 "match metric <0-4294967295>",
561 "Match metric of route\n"
564 return rip_route_match_add (vty
, vty
->index
, "metric", argv
[0]);
567 DEFUN (no_match_metric
,
572 "Match metric of route\n")
575 return rip_route_match_delete (vty
, vty
->index
, "metric", NULL
);
577 return rip_route_match_delete (vty
, vty
->index
, "metric", argv
[0]);
580 ALIAS (no_match_metric
,
581 no_match_metric_val_cmd
,
582 "no match metric <0-4294967295>",
585 "Match metric of route\n"
588 DEFUN (match_interface
,
590 "match interface WORD",
592 "Match first hop interface of route\n"
595 return rip_route_match_add (vty
, vty
->index
, "interface", argv
[0]);
598 DEFUN (no_match_interface
,
599 no_match_interface_cmd
,
600 "no match interface",
603 "Match first hop interface of route\n")
606 return rip_route_match_delete (vty
, vty
->index
, "interface", NULL
);
608 return rip_route_match_delete (vty
, vty
->index
, "interface", argv
[0]);
611 ALIAS (no_match_interface
,
612 no_match_interface_val_cmd
,
613 "no match interface WORD",
616 "Match first hop interface of route\n"
619 DEFUN (match_ip_next_hop
,
620 match_ip_next_hop_cmd
,
621 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
624 "Match next-hop address of route\n"
625 "IP access-list number\n"
626 "IP access-list number (expanded range)\n"
627 "IP Access-list name\n")
629 return rip_route_match_add (vty
, vty
->index
, "ip next-hop", argv
[0]);
632 DEFUN (no_match_ip_next_hop
,
633 no_match_ip_next_hop_cmd
,
634 "no match ip next-hop",
638 "Match next-hop address of route\n")
641 return rip_route_match_delete (vty
, vty
->index
, "ip next-hop", NULL
);
643 return rip_route_match_delete (vty
, vty
->index
, "ip next-hop", argv
[0]);
646 ALIAS (no_match_ip_next_hop
,
647 no_match_ip_next_hop_val_cmd
,
648 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
652 "Match next-hop address of route\n"
653 "IP access-list number\n"
654 "IP access-list number (expanded range)\n"
655 "IP Access-list name\n");
657 DEFUN (match_ip_next_hop_prefix_list
,
658 match_ip_next_hop_prefix_list_cmd
,
659 "match ip next-hop prefix-list WORD",
662 "Match next-hop address of route\n"
663 "Match entries of prefix-lists\n"
664 "IP prefix-list name\n")
666 return rip_route_match_add (vty
, vty
->index
, "ip next-hop prefix-list", argv
[0]);
669 DEFUN (no_match_ip_next_hop_prefix_list
,
670 no_match_ip_next_hop_prefix_list_cmd
,
671 "no match ip next-hop prefix-list",
675 "Match next-hop address of route\n"
676 "Match entries of prefix-lists\n")
679 return rip_route_match_delete (vty
, vty
->index
, "ip next-hop prefix-list", NULL
);
681 return rip_route_match_delete (vty
, vty
->index
, "ip next-hop prefix-list", argv
[0]);
684 ALIAS (no_match_ip_next_hop_prefix_list
,
685 no_match_ip_next_hop_prefix_list_val_cmd
,
686 "no match ip next-hop prefix-list WORD",
690 "Match next-hop address of route\n"
691 "Match entries of prefix-lists\n"
692 "IP prefix-list name\n");
694 DEFUN (match_ip_address
,
695 match_ip_address_cmd
,
696 "match ip address (<1-199>|<1300-2699>|WORD)",
699 "Match address of route\n"
700 "IP access-list number\n"
701 "IP access-list number (expanded range)\n"
702 "IP Access-list name\n")
705 return rip_route_match_add (vty
, vty
->index
, "ip address", argv
[0]);
708 DEFUN (no_match_ip_address
,
709 no_match_ip_address_cmd
,
710 "no match ip address",
714 "Match address of route\n")
717 return rip_route_match_delete (vty
, vty
->index
, "ip address", NULL
);
719 return rip_route_match_delete (vty
, vty
->index
, "ip address", argv
[0]);
722 ALIAS (no_match_ip_address
,
723 no_match_ip_address_val_cmd
,
724 "no match ip address (<1-199>|<1300-2699>|WORD)",
728 "Match address of route\n"
729 "IP access-list number\n"
730 "IP access-list number (expanded range)\n"
731 "IP Access-list name\n");
733 DEFUN (match_ip_address_prefix_list
,
734 match_ip_address_prefix_list_cmd
,
735 "match ip address prefix-list WORD",
738 "Match address of route\n"
739 "Match entries of prefix-lists\n"
740 "IP prefix-list name\n")
742 return rip_route_match_add (vty
, vty
->index
, "ip address prefix-list", argv
[0]);
745 DEFUN (no_match_ip_address_prefix_list
,
746 no_match_ip_address_prefix_list_cmd
,
747 "no match ip address prefix-list",
751 "Match address of route\n"
752 "Match entries of prefix-lists\n")
755 return rip_route_match_delete (vty
, vty
->index
, "ip address prefix-list", NULL
);
757 return rip_route_match_delete (vty
, vty
->index
, "ip address prefix-list", argv
[0]);
760 ALIAS (no_match_ip_address_prefix_list
,
761 no_match_ip_address_prefix_list_val_cmd
,
762 "no match ip address prefix-list WORD",
766 "Match address of route\n"
767 "Match entries of prefix-lists\n"
768 "IP prefix-list name\n");
774 "set metric <0-4294967295>",
776 "Metric value for destination routing protocol\n"
779 return rip_route_set_add (vty
, vty
->index
, "metric", argv
[0]);
782 DEFUN (no_set_metric
,
787 "Metric value for destination routing protocol\n")
790 return rip_route_set_delete (vty
, vty
->index
, "metric", NULL
);
792 return rip_route_set_delete (vty
, vty
->index
, "metric", argv
[0]);
795 ALIAS (no_set_metric
,
796 no_set_metric_val_cmd
,
797 "no set metric <0-4294967295>",
800 "Metric value for destination routing protocol\n"
803 DEFUN (set_ip_nexthop
,
805 "set ip next-hop A.B.C.D",
809 "IP address of next hop\n")
814 ret
= str2sockunion (argv
[0], &su
);
817 vty_out (vty
, "%% Malformed next-hop address%s", VTY_NEWLINE
);
821 return rip_route_set_add (vty
, vty
->index
, "ip next-hop", argv
[0]);
824 DEFUN (no_set_ip_nexthop
,
825 no_set_ip_nexthop_cmd
,
826 "no set ip next-hop",
830 "Next hop address\n")
833 return rip_route_set_delete (vty
, vty
->index
, "ip next-hop", NULL
);
835 return rip_route_set_delete (vty
, vty
->index
, "ip next-hop", argv
[0]);
838 ALIAS (no_set_ip_nexthop
,
839 no_set_ip_nexthop_val_cmd
,
840 "no set ip next-hop A.B.C.D",
845 "IP address of next hop\n");
848 rip_route_map_reset ()
855 rip_route_map_init ()
858 route_map_init_vty ();
859 route_map_add_hook (rip_route_map_update
);
860 route_map_delete_hook (rip_route_map_update
);
862 route_map_install_match (&route_match_metric_cmd
);
863 route_map_install_match (&route_match_interface_cmd
);
864 route_map_install_match (&route_match_ip_next_hop_cmd
);
865 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
866 route_map_install_match (&route_match_ip_address_cmd
);
867 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
869 route_map_install_set (&route_set_metric_cmd
);
870 route_map_install_set (&route_set_ip_nexthop_cmd
);
872 install_element (RMAP_NODE
, &match_metric_cmd
);
873 install_element (RMAP_NODE
, &no_match_metric_cmd
);
874 install_element (RMAP_NODE
, &no_match_metric_val_cmd
);
875 install_element (RMAP_NODE
, &match_interface_cmd
);
876 install_element (RMAP_NODE
, &no_match_interface_cmd
);
877 install_element (RMAP_NODE
, &no_match_interface_val_cmd
);
878 install_element (RMAP_NODE
, &match_ip_next_hop_cmd
);
879 install_element (RMAP_NODE
, &no_match_ip_next_hop_cmd
);
880 install_element (RMAP_NODE
, &no_match_ip_next_hop_val_cmd
);
881 install_element (RMAP_NODE
, &match_ip_next_hop_prefix_list_cmd
);
882 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_cmd
);
883 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_val_cmd
);
884 install_element (RMAP_NODE
, &match_ip_address_cmd
);
885 install_element (RMAP_NODE
, &no_match_ip_address_cmd
);
886 install_element (RMAP_NODE
, &no_match_ip_address_val_cmd
);
887 install_element (RMAP_NODE
, &match_ip_address_prefix_list_cmd
);
888 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_cmd
);
889 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_val_cmd
);
891 install_element (RMAP_NODE
, &set_metric_cmd
);
892 install_element (RMAP_NODE
, &no_set_metric_cmd
);
893 install_element (RMAP_NODE
, &no_set_metric_val_cmd
);
894 install_element (RMAP_NODE
, &set_ip_nexthop_cmd
);
895 install_element (RMAP_NODE
, &no_set_ip_nexthop_cmd
);
896 install_element (RMAP_NODE
, &no_set_ip_nexthop_val_cmd
);