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 /* To make it consistent to other daemon, metric check is commented
480 if (*metric
>= 0 && *metric
<= 16)
483 XFREE (MTYPE_ROUTE_MAP_COMPILED
, metric
);
488 /* Free route map's compiled `set metric' value. */
490 route_set_metric_free (void *rule
)
492 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
495 /* Set metric rule structure. */
496 struct route_map_rule_cmd route_set_metric_cmd
=
500 route_set_metric_compile
,
501 route_set_metric_free
,
504 /* `set ip next-hop IP_ADDRESS' */
506 /* Set nexthop to object. ojbect must be pointer to struct attr. */
508 route_set_ip_nexthop (void *rule
, struct prefix
*prefix
,
509 route_map_object_t type
, void *object
)
511 struct in_addr
*address
;
512 struct rip_info
*rinfo
;
516 /* Fetch routemap's rule information. */
520 /* Set next hop value. */
521 rinfo
->nexthop_out
= *address
;
527 /* Route map `ip nexthop' compile function. Given string is converted
528 to struct in_addr structure. */
530 route_set_ip_nexthop_compile (char *arg
)
533 struct in_addr
*address
;
535 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
537 ret
= inet_aton (arg
, address
);
541 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
548 /* Free route map's compiled `ip nexthop' value. */
550 route_set_ip_nexthop_free (void *rule
)
552 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
555 /* Route map commands for ip nexthop set. */
556 struct route_map_rule_cmd route_set_ip_nexthop_cmd
=
559 route_set_ip_nexthop
,
560 route_set_ip_nexthop_compile
,
561 route_set_ip_nexthop_free
564 #define MATCH_STR "Match values from routing table\n"
565 #define SET_STR "Set values in destination routing protocol\n"
569 "match metric <0-4294967295>",
571 "Match metric of route\n"
574 return rip_route_match_add (vty
, vty
->index
, "metric", argv
[0]);
577 DEFUN (no_match_metric
,
582 "Match metric of route\n")
585 return rip_route_match_delete (vty
, vty
->index
, "metric", NULL
);
587 return rip_route_match_delete (vty
, vty
->index
, "metric", argv
[0]);
590 ALIAS (no_match_metric
,
591 no_match_metric_val_cmd
,
592 "no match metric <0-4294967295>",
595 "Match metric of route\n"
598 DEFUN (match_interface
,
600 "match interface WORD",
602 "Match first hop interface of route\n"
605 return rip_route_match_add (vty
, vty
->index
, "interface", argv
[0]);
608 DEFUN (no_match_interface
,
609 no_match_interface_cmd
,
610 "no match interface",
613 "Match first hop interface of route\n")
616 return rip_route_match_delete (vty
, vty
->index
, "interface", NULL
);
618 return rip_route_match_delete (vty
, vty
->index
, "interface", argv
[0]);
621 ALIAS (no_match_interface
,
622 no_match_interface_val_cmd
,
623 "no match interface WORD",
626 "Match first hop interface of route\n"
629 DEFUN (match_ip_next_hop
,
630 match_ip_next_hop_cmd
,
631 "match ip next-hop WORD",
634 "Match next-hop address of route\n"
635 "IP access-list name\n")
637 return rip_route_match_add (vty
, vty
->index
, "ip next-hop", argv
[0]);
640 DEFUN (no_match_ip_next_hop
,
641 no_match_ip_next_hop_cmd
,
642 "no match ip next-hop",
646 "Match next-hop address of route\n")
649 return rip_route_match_delete (vty
, vty
->index
, "ip next-hop", NULL
);
651 return rip_route_match_delete (vty
, vty
->index
, "ip next-hop", argv
[0]);
654 ALIAS (no_match_ip_next_hop
,
655 no_match_ip_next_hop_val_cmd
,
656 "no match ip next-hop WORD",
660 "Match next-hop address of route\n"
661 "IP access-list name\n")
663 DEFUN (match_ip_next_hop_prefix_list
,
664 match_ip_next_hop_prefix_list_cmd
,
665 "match ip next-hop prefix-list WORD",
668 "Match next-hop address of route\n"
669 "Match entries of prefix-lists\n"
670 "IP prefix-list name\n")
672 return rip_route_match_add (vty
, vty
->index
, "ip next-hop prefix-list", argv
[0]);
675 DEFUN (no_match_ip_next_hop_prefix_list
,
676 no_match_ip_next_hop_prefix_list_cmd
,
677 "no match ip next-hop prefix-list",
681 "Match next-hop address of route\n"
682 "Match entries of prefix-lists\n")
685 return rip_route_match_delete (vty
, vty
->index
, "ip next-hop prefix-list", NULL
);
687 return rip_route_match_delete (vty
, vty
->index
, "ip next-hop prefix-list", argv
[0]);
690 ALIAS (no_match_ip_next_hop_prefix_list
,
691 no_match_ip_next_hop_prefix_list_val_cmd
,
692 "no match ip next-hop prefix-list WORD",
696 "Match next-hop address of route\n"
697 "Match entries of prefix-lists\n"
698 "IP prefix-list name\n")
700 DEFUN (match_ip_address
,
701 match_ip_address_cmd
,
702 "match ip address WORD",
705 "Match address of route\n"
706 "IP access-list name\n")
708 return rip_route_match_add (vty
, vty
->index
, "ip address", argv
[0]);
711 DEFUN (no_match_ip_address
,
712 no_match_ip_address_cmd
,
713 "no match ip address",
717 "Match address of route\n")
720 return rip_route_match_delete (vty
, vty
->index
, "ip address", NULL
);
722 return rip_route_match_delete (vty
, vty
->index
, "ip address", argv
[0]);
725 ALIAS (no_match_ip_address
,
726 no_match_ip_address_val_cmd
,
727 "no match ip address WORD",
731 "Match address of route\n"
732 "IP access-list name\n")
734 DEFUN (match_ip_address_prefix_list
,
735 match_ip_address_prefix_list_cmd
,
736 "match ip address prefix-list WORD",
739 "Match address of route\n"
740 "Match entries of prefix-lists\n"
741 "IP prefix-list name\n")
743 return rip_route_match_add (vty
, vty
->index
, "ip address prefix-list", argv
[0]);
746 DEFUN (no_match_ip_address_prefix_list
,
747 no_match_ip_address_prefix_list_cmd
,
748 "no match ip address prefix-list",
752 "Match address of route\n"
753 "Match entries of prefix-lists\n")
756 return rip_route_match_delete (vty
, vty
->index
, "ip address prefix-list", NULL
);
758 return rip_route_match_delete (vty
, vty
->index
, "ip address prefix-list", argv
[0]);
761 ALIAS (no_match_ip_address_prefix_list
,
762 no_match_ip_address_prefix_list_val_cmd
,
763 "no match ip address prefix-list WORD",
767 "Match address of route\n"
768 "Match entries of prefix-lists\n"
769 "IP prefix-list name\n")
775 "set metric <0-4294967295>",
777 "Metric value for destination routing protocol\n"
780 return rip_route_set_add (vty
, vty
->index
, "metric", argv
[0]);
783 DEFUN (no_set_metric
,
788 "Metric value for destination routing protocol\n")
791 return rip_route_set_delete (vty
, vty
->index
, "metric", NULL
);
793 return rip_route_set_delete (vty
, vty
->index
, "metric", argv
[0]);
796 ALIAS (no_set_metric
,
797 no_set_metric_val_cmd
,
798 "no set metric <0-4294967295>",
801 "Metric value for destination routing protocol\n"
804 DEFUN (set_ip_nexthop
,
806 "set ip next-hop A.B.C.D",
810 "IP address of next hop\n")
815 ret
= str2sockunion (argv
[0], &su
);
818 vty_out (vty
, "%% Malformed next-hop address%s", VTY_NEWLINE
);
822 return rip_route_set_add (vty
, vty
->index
, "ip next-hop", argv
[0]);
825 DEFUN (no_set_ip_nexthop
,
826 no_set_ip_nexthop_cmd
,
827 "no set ip next-hop",
831 "Next hop address\n")
834 return rip_route_set_delete (vty
, vty
->index
, "ip next-hop", NULL
);
836 return rip_route_set_delete (vty
, vty
->index
, "ip next-hop", argv
[0]);
839 ALIAS (no_set_ip_nexthop
,
840 no_set_ip_nexthop_val_cmd
,
841 "no set ip next-hop A.B.C.D",
846 "IP address of next hop\n")
849 rip_route_map_reset ()
856 rip_route_map_init ()
859 route_map_init_vty ();
860 route_map_add_hook (rip_route_map_update
);
861 route_map_delete_hook (rip_route_map_update
);
863 route_map_install_match (&route_match_metric_cmd
);
864 route_map_install_match (&route_match_interface_cmd
);
865 route_map_install_match (&route_match_ip_next_hop_cmd
);
866 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
867 route_map_install_match (&route_match_ip_address_cmd
);
868 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
870 route_map_install_set (&route_set_metric_cmd
);
871 route_map_install_set (&route_set_ip_nexthop_cmd
);
873 install_element (RMAP_NODE
, &match_metric_cmd
);
874 install_element (RMAP_NODE
, &no_match_metric_cmd
);
875 install_element (RMAP_NODE
, &no_match_metric_val_cmd
);
876 install_element (RMAP_NODE
, &match_interface_cmd
);
877 install_element (RMAP_NODE
, &no_match_interface_cmd
);
878 install_element (RMAP_NODE
, &no_match_interface_val_cmd
);
879 install_element (RMAP_NODE
, &match_ip_next_hop_cmd
);
880 install_element (RMAP_NODE
, &no_match_ip_next_hop_cmd
);
881 install_element (RMAP_NODE
, &no_match_ip_next_hop_val_cmd
);
882 install_element (RMAP_NODE
, &match_ip_next_hop_prefix_list_cmd
);
883 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_cmd
);
884 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_val_cmd
);
885 install_element (RMAP_NODE
, &match_ip_address_cmd
);
886 install_element (RMAP_NODE
, &no_match_ip_address_cmd
);
887 install_element (RMAP_NODE
, &no_match_ip_address_val_cmd
);
888 install_element (RMAP_NODE
, &match_ip_address_prefix_list_cmd
);
889 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_cmd
);
890 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_val_cmd
);
892 install_element (RMAP_NODE
, &set_metric_cmd
);
893 install_element (RMAP_NODE
, &no_set_metric_cmd
);
894 install_element (RMAP_NODE
, &no_set_metric_val_cmd
);
895 install_element (RMAP_NODE
, &set_ip_nexthop_cmd
);
896 install_element (RMAP_NODE
, &no_set_ip_nexthop_cmd
);
897 install_element (RMAP_NODE
, &no_set_ip_nexthop_val_cmd
);