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
 
  31 #include "sockunion.h"          /* for inet_aton () */
 
  34 #include "ripd/ripd.h"
 
  36 struct rip_metric_modifier
 
  48 /* Add rip route map rule. */
 
  50 rip_route_match_add (struct vty *vty, struct route_map_index *index,
 
  51                      const char *command, const char *arg)
 
  55   ret = route_map_add_match (index, command, arg);
 
  60         case RMAP_RULE_MISSING:
 
  61           vty_out (vty, "%% RIP Can't find rule.%s", VTY_NEWLINE);
 
  63         case RMAP_COMPILE_ERROR:
 
  64           vty_out (vty, "%% RIP Argument is malformed.%s", VTY_NEWLINE);
 
  71 /* Delete rip route map rule. */
 
  73 rip_route_match_delete (struct vty *vty, struct route_map_index *index,
 
  74                         const char *command, const char *arg)
 
  78   ret = route_map_delete_match (index, command, arg);
 
  83         case RMAP_RULE_MISSING:
 
  84           vty_out (vty, "%% RIP Can't find rule.%s", VTY_NEWLINE);
 
  86         case RMAP_COMPILE_ERROR:
 
  87           vty_out (vty, "%% RIP Argument is malformed.%s", VTY_NEWLINE);
 
  94 /* Add rip route map rule. */
 
  96 rip_route_set_add (struct vty *vty, struct route_map_index *index,
 
  97                    const char *command, const char *arg)
 
 101   ret = route_map_add_set (index, command, arg);
 
 106         case RMAP_RULE_MISSING:
 
 107           vty_out (vty, "%% RIP Can't find rule.%s", VTY_NEWLINE);
 
 109         case RMAP_COMPILE_ERROR:
 
 110           /* rip, ripng and other protocols share the set metric command
 
 111              but only values from 0 to 16 are valid for rip and ripng
 
 112              if metric is out of range for rip and ripng, it is not for
 
 113              other protocols. Do not return an error */
 
 114           if (strcmp(command, "metric")) {
 
 115              vty_out (vty, "%% RIP Argument is malformed.%s", VTY_NEWLINE);
 
 123 /* Delete rip route map rule. */
 
 125 rip_route_set_delete (struct vty *vty, struct route_map_index *index,
 
 126                       const char *command, const char *arg)
 
 130   ret = route_map_delete_set (index, command, arg);
 
 135         case RMAP_RULE_MISSING:
 
 136           vty_out (vty, "%% RIP Can't find rule.%s", VTY_NEWLINE);
 
 138         case RMAP_COMPILE_ERROR:
 
 139           vty_out (vty, "%% RIP Argument is malformed.%s", VTY_NEWLINE);
 
 146 /* Hook function for updating route_map assignment. */
 
 149 rip_route_map_update (const char *notused)
 
 155       for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
 
 157           if (rip->route_map[i].name)
 
 158             rip->route_map[i].map = 
 
 159               route_map_lookup_by_name (rip->route_map[i].name);
 
 164 /* `match metric METRIC' */
 
 165 /* Match function return 1 if match is success else return zero. */
 
 166 static route_map_result_t
 
 167 route_match_metric (void *rule, struct prefix *prefix, 
 
 168                     route_map_object_t type, void *object)
 
 172   struct rip_info *rinfo;
 
 174   if (type == RMAP_RIP)
 
 179       /* If external metric is available, the route-map should
 
 180          work on this one (for redistribute purpose)  */
 
 181       check = (rinfo->external_metric) ? rinfo->external_metric :
 
 183       if (check == *metric)
 
 191 /* Route map `match metric' match statement. `arg' is METRIC value */
 
 193 route_match_metric_compile (const char *arg)
 
 197   metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
 
 198   *metric = atoi (arg);
 
 203   XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
 
 207 /* Free route map's compiled `match metric' value. */
 
 209 route_match_metric_free (void *rule)
 
 211   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 214 /* Route map commands for metric matching. */
 
 215 struct route_map_rule_cmd route_match_metric_cmd =
 
 219   route_match_metric_compile,
 
 220   route_match_metric_free
 
 223 /* `match interface IFNAME' */
 
 224 /* Match function return 1 if match is success else return zero. */
 
 225 static route_map_result_t
 
 226 route_match_interface (void *rule, struct prefix *prefix,
 
 227                        route_map_object_t type, void *object)
 
 229   struct rip_info *rinfo;
 
 230   struct interface *ifp;
 
 233   if (type == RMAP_RIP)
 
 236       ifp = if_lookup_by_name(ifname);
 
 243       if (rinfo->ifindex_out == ifp->ifindex || rinfo->ifindex == ifp->ifindex)
 
 251 /* Route map `match interface' match statement. `arg' is IFNAME value */
 
 252 /* XXX I don`t know if I need to check does interface exist? */
 
 254 route_match_interface_compile (const char *arg)
 
 256   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 259 /* Free route map's compiled `match interface' value. */
 
 261 route_match_interface_free (void *rule)
 
 263   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 266 /* Route map commands for interface matching. */
 
 267 struct route_map_rule_cmd route_match_interface_cmd =
 
 270   route_match_interface,
 
 271   route_match_interface_compile,
 
 272   route_match_interface_free
 
 275 /* `match ip next-hop IP_ACCESS_LIST' */
 
 277 /* Match function return 1 if match is success else return zero. */
 
 278 static route_map_result_t
 
 279 route_match_ip_next_hop (void *rule, struct prefix *prefix,
 
 280                         route_map_object_t type, void *object)
 
 282   struct access_list *alist;
 
 283   struct rip_info *rinfo;
 
 284   struct prefix_ipv4 p;
 
 286   if (type == RMAP_RIP)
 
 290       p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;
 
 291       p.prefixlen = IPV4_MAX_BITLEN;
 
 293       alist = access_list_lookup (AFI_IP, (char *) rule);
 
 297       return (access_list_apply (alist, &p) == FILTER_DENY ?
 
 298               RMAP_NOMATCH : RMAP_MATCH);
 
 303 /* Route map `ip next-hop' match statement.  `arg' should be
 
 306 route_match_ip_next_hop_compile (const char *arg)
 
 308   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 311 /* Free route map's compiled `. */
 
 313 route_match_ip_next_hop_free (void *rule)
 
 315   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 318 /* Route map commands for ip next-hop matching. */
 
 319 static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
 
 322   route_match_ip_next_hop,
 
 323   route_match_ip_next_hop_compile,
 
 324   route_match_ip_next_hop_free
 
 327 /* `match ip next-hop prefix-list PREFIX_LIST' */
 
 329 static route_map_result_t
 
 330 route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
 
 331                                     route_map_object_t type, void *object)
 
 333   struct prefix_list *plist;
 
 334   struct rip_info *rinfo;
 
 335   struct prefix_ipv4 p;
 
 337   if (type == RMAP_RIP)
 
 341       p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;
 
 342       p.prefixlen = IPV4_MAX_BITLEN;
 
 344       plist = prefix_list_lookup (AFI_IP, (char *) rule);
 
 348       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
 
 349               RMAP_NOMATCH : RMAP_MATCH);
 
 355 route_match_ip_next_hop_prefix_list_compile (const char *arg)
 
 357   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 361 route_match_ip_next_hop_prefix_list_free (void *rule)
 
 363   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 366 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
 
 368   "ip next-hop prefix-list",
 
 369   route_match_ip_next_hop_prefix_list,
 
 370   route_match_ip_next_hop_prefix_list_compile,
 
 371   route_match_ip_next_hop_prefix_list_free
 
 374 /* `match ip address IP_ACCESS_LIST' */
 
 376 /* Match function should return 1 if match is success else return
 
 378 static route_map_result_t
 
 379 route_match_ip_address (void *rule, struct prefix *prefix, 
 
 380                         route_map_object_t type, void *object)
 
 382   struct access_list *alist;
 
 384   if (type == RMAP_RIP)
 
 386       alist = access_list_lookup (AFI_IP, (char *) rule);
 
 390       return (access_list_apply (alist, prefix) == FILTER_DENY ?
 
 391               RMAP_NOMATCH : RMAP_MATCH);
 
 396 /* Route map `ip address' match statement.  `arg' should be
 
 399 route_match_ip_address_compile (const char *arg)
 
 401   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 404 /* Free route map's compiled `ip address' value. */
 
 406 route_match_ip_address_free (void *rule)
 
 408   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 411 /* Route map commands for ip address matching. */
 
 412 static struct route_map_rule_cmd route_match_ip_address_cmd =
 
 415   route_match_ip_address,
 
 416   route_match_ip_address_compile,
 
 417   route_match_ip_address_free
 
 420 /* `match ip address prefix-list PREFIX_LIST' */
 
 422 static route_map_result_t
 
 423 route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, 
 
 424                                     route_map_object_t type, void *object)
 
 426   struct prefix_list *plist;
 
 428   if (type == RMAP_RIP)
 
 430       plist = prefix_list_lookup (AFI_IP, (char *) rule);
 
 434       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
 
 435               RMAP_NOMATCH : RMAP_MATCH);
 
 441 route_match_ip_address_prefix_list_compile (const char *arg)
 
 443   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 447 route_match_ip_address_prefix_list_free (void *rule)
 
 449   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 452 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
 
 454   "ip address prefix-list",
 
 455   route_match_ip_address_prefix_list,
 
 456   route_match_ip_address_prefix_list_compile,
 
 457   route_match_ip_address_prefix_list_free
 
 460 /* `match tag TAG' */
 
 461 /* Match function return 1 if match is success else return zero. */
 
 462 static route_map_result_t
 
 463 route_match_tag (void *rule, struct prefix *prefix, 
 
 464                     route_map_object_t type, void *object)
 
 467   struct rip_info *rinfo;
 
 469   if (type == RMAP_RIP)
 
 474       /* The information stored by rinfo is host ordered. */
 
 475       if (rinfo->tag == *tag)
 
 483 /* Route map commands for tag matching. */
 
 484 static struct route_map_rule_cmd route_match_tag_cmd =
 
 488   route_map_rule_tag_compile,
 
 489   route_map_rule_tag_free,
 
 492 /* `set metric METRIC' */
 
 494 /* Set metric to attribute. */
 
 495 static route_map_result_t
 
 496 route_set_metric (void *rule, struct prefix *prefix, 
 
 497                   route_map_object_t type, void *object)
 
 499   if (type == RMAP_RIP)
 
 501       struct rip_metric_modifier *mod;
 
 502       struct rip_info *rinfo;
 
 507       if (mod->type == metric_increment)
 
 508         rinfo->metric_out += mod->metric;
 
 509       else if (mod->type == metric_decrement)
 
 510         rinfo->metric_out -= mod->metric;
 
 511       else if (mod->type == metric_absolute)
 
 512         rinfo->metric_out = mod->metric;
 
 514       if ((signed int)rinfo->metric_out < 1)
 
 515         rinfo->metric_out = 1;
 
 516       if (rinfo->metric_out > RIP_METRIC_INFINITY)
 
 517         rinfo->metric_out = RIP_METRIC_INFINITY;
 
 519       rinfo->metric_set = 1;
 
 524 /* set metric compilation. */
 
 526 route_set_metric_compile (const char *arg)
 
 533   struct rip_metric_modifier *mod;
 
 541   /* Examine first character. */
 
 544       type = metric_increment;
 
 547   else if (arg[0] == '-')
 
 549       type = metric_decrement;
 
 553     type = metric_absolute;
 
 555   /* Check beginning with digit string. */
 
 556   if (*pnt < '0' || *pnt > '9')
 
 559   /* Convert string to integer. */
 
 560   metric = strtol (pnt, &endptr, 10);
 
 562   if (metric == LONG_MAX || *endptr != '\0')
 
 564   if (metric < 0 || metric > RIP_METRIC_INFINITY)
 
 567   mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, 
 
 568                  sizeof (struct rip_metric_modifier));
 
 570   mod->metric = metric;
 
 575 /* Free route map's compiled `set metric' value. */
 
 577 route_set_metric_free (void *rule)
 
 579   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 582 /* Set metric rule structure. */
 
 583 static struct route_map_rule_cmd route_set_metric_cmd = 
 
 587   route_set_metric_compile,
 
 588   route_set_metric_free,
 
 591 /* `set ip next-hop IP_ADDRESS' */
 
 593 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 
 594 static route_map_result_t
 
 595 route_set_ip_nexthop (void *rule, struct prefix *prefix, 
 
 596                       route_map_object_t type, void *object)
 
 598   struct in_addr *address;
 
 599   struct rip_info *rinfo;
 
 603       /* Fetch routemap's rule information. */
 
 607       /* Set next hop value. */ 
 
 608       rinfo->nexthop_out = *address;
 
 614 /* Route map `ip nexthop' compile function.  Given string is converted
 
 615    to struct in_addr structure. */
 
 617 route_set_ip_nexthop_compile (const char *arg)
 
 620   struct in_addr *address;
 
 622   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
 
 624   ret = inet_aton (arg, address);
 
 628       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
 
 635 /* Free route map's compiled `ip nexthop' value. */
 
 637 route_set_ip_nexthop_free (void *rule)
 
 639   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 642 /* Route map commands for ip nexthop set. */
 
 643 static struct route_map_rule_cmd route_set_ip_nexthop_cmd =
 
 646   route_set_ip_nexthop,
 
 647   route_set_ip_nexthop_compile,
 
 648   route_set_ip_nexthop_free
 
 653 /* Set tag to object.  ojbect must be pointer to struct attr. */
 
 654 static route_map_result_t
 
 655 route_set_tag (void *rule, struct prefix *prefix, 
 
 656                       route_map_object_t type, void *object)
 
 659   struct rip_info *rinfo;
 
 663       /* Fetch routemap's rule information. */
 
 667       /* Set next hop value. */ 
 
 668       rinfo->tag_out = *tag;
 
 674 /* Route map commands for tag set. */
 
 675 static struct route_map_rule_cmd route_set_tag_cmd =
 
 679   route_map_rule_tag_compile,
 
 680   route_map_rule_tag_free
 
 683 #define MATCH_STR "Match values from routing table\n"
 
 684 #define SET_STR "Set values in destination routing protocol\n"
 
 688        "match metric <0-4294967295>",
 
 690        "Match metric of route\n"
 
 693   return rip_route_match_add (vty, vty->index, "metric", argv[0]);
 
 696 DEFUN (no_match_metric,
 
 701        "Match metric of route\n")
 
 704     return rip_route_match_delete (vty, vty->index, "metric", NULL);
 
 706   return rip_route_match_delete (vty, vty->index, "metric", argv[0]);
 
 709 ALIAS (no_match_metric,
 
 710        no_match_metric_val_cmd,
 
 711        "no match metric <0-4294967295>",
 
 714        "Match metric of route\n"
 
 717 DEFUN (match_interface,
 
 719        "match interface WORD",
 
 721        "Match first hop interface of route\n"
 
 724   return rip_route_match_add (vty, vty->index, "interface", argv[0]);
 
 727 DEFUN (no_match_interface,
 
 728        no_match_interface_cmd,
 
 729        "no match interface",
 
 732        "Match first hop interface of route\n")
 
 735     return rip_route_match_delete (vty, vty->index, "interface", NULL);
 
 737   return rip_route_match_delete (vty, vty->index, "interface", argv[0]);
 
 740 ALIAS (no_match_interface,
 
 741        no_match_interface_val_cmd,
 
 742        "no match interface WORD",
 
 745        "Match first hop interface of route\n"
 
 748 DEFUN (match_ip_next_hop,
 
 749        match_ip_next_hop_cmd,
 
 750        "match ip next-hop (<1-199>|<1300-2699>|WORD)",
 
 753        "Match next-hop address of route\n"
 
 754        "IP access-list number\n"
 
 755        "IP access-list number (expanded range)\n"
 
 756        "IP Access-list name\n")
 
 758   return rip_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
 
 761 DEFUN (no_match_ip_next_hop,
 
 762        no_match_ip_next_hop_cmd,
 
 763        "no match ip next-hop",
 
 767        "Match next-hop address of route\n")
 
 770     return rip_route_match_delete (vty, vty->index, "ip next-hop", NULL);
 
 772   return rip_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
 
 775 ALIAS (no_match_ip_next_hop,
 
 776        no_match_ip_next_hop_val_cmd,
 
 777        "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
 
 781        "Match next-hop address of route\n"
 
 782        "IP access-list number\n"
 
 783        "IP access-list number (expanded range)\n"
 
 784        "IP Access-list name\n")
 
 786 DEFUN (match_ip_next_hop_prefix_list,
 
 787        match_ip_next_hop_prefix_list_cmd,
 
 788        "match ip next-hop prefix-list WORD",
 
 791        "Match next-hop address of route\n"
 
 792        "Match entries of prefix-lists\n"
 
 793        "IP prefix-list name\n")
 
 795   return rip_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
 
 798 DEFUN (no_match_ip_next_hop_prefix_list,
 
 799        no_match_ip_next_hop_prefix_list_cmd,
 
 800        "no match ip next-hop prefix-list",
 
 804        "Match next-hop address of route\n"
 
 805        "Match entries of prefix-lists\n")
 
 808     return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
 
 810   return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
 
 813 ALIAS (no_match_ip_next_hop_prefix_list,
 
 814        no_match_ip_next_hop_prefix_list_val_cmd,
 
 815        "no match ip next-hop prefix-list WORD",
 
 819        "Match next-hop address of route\n"
 
 820        "Match entries of prefix-lists\n"
 
 821        "IP prefix-list name\n")
 
 823 DEFUN (match_ip_address,
 
 824        match_ip_address_cmd,
 
 825        "match ip address (<1-199>|<1300-2699>|WORD)",
 
 828        "Match address of route\n"
 
 829        "IP access-list number\n"
 
 830        "IP access-list number (expanded range)\n"
 
 831        "IP Access-list name\n")
 
 834   return rip_route_match_add (vty, vty->index, "ip address", argv[0]);
 
 837 DEFUN (no_match_ip_address, 
 
 838        no_match_ip_address_cmd,
 
 839        "no match ip address",
 
 843        "Match address of route\n")
 
 846     return rip_route_match_delete (vty, vty->index, "ip address", NULL);
 
 848   return rip_route_match_delete (vty, vty->index, "ip address", argv[0]);
 
 851 ALIAS (no_match_ip_address,
 
 852        no_match_ip_address_val_cmd,
 
 853        "no match ip address (<1-199>|<1300-2699>|WORD)",
 
 857        "Match address of route\n"
 
 858        "IP access-list number\n"
 
 859        "IP access-list number (expanded range)\n"
 
 860        "IP Access-list name\n")
 
 862 DEFUN (match_ip_address_prefix_list, 
 
 863        match_ip_address_prefix_list_cmd,
 
 864        "match ip address prefix-list WORD",
 
 867        "Match address of route\n"
 
 868        "Match entries of prefix-lists\n"
 
 869        "IP prefix-list name\n")
 
 871   return rip_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
 
 874 DEFUN (no_match_ip_address_prefix_list,
 
 875        no_match_ip_address_prefix_list_cmd,
 
 876        "no match ip address prefix-list",
 
 880        "Match address of route\n"
 
 881        "Match entries of prefix-lists\n")
 
 884     return rip_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
 
 886   return rip_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
 
 889 ALIAS (no_match_ip_address_prefix_list,
 
 890        no_match_ip_address_prefix_list_val_cmd,
 
 891        "no match ip address prefix-list WORD",
 
 895        "Match address of route\n"
 
 896        "Match entries of prefix-lists\n"
 
 897        "IP prefix-list name\n")
 
 901        "match tag <1-4294967295>",
 
 903        "Match tag of route\n"
 
 906   return rip_route_match_add (vty, vty->index, "tag", argv[0]);
 
 914        "Match tag of route\n")
 
 917     return rip_route_match_delete (vty, vty->index, "tag", NULL);
 
 919   return rip_route_match_delete (vty, vty->index, "tag", argv[0]);
 
 923        no_match_tag_val_cmd,
 
 924        "no match tag <1-4294967295>",
 
 927        "Match tag of route\n"
 
 934        "set metric <0-4294967295>",
 
 936        "Metric value for destination routing protocol\n"
 
 939   return rip_route_set_add (vty, vty->index, "metric", argv[0]);
 
 943        set_metric_addsub_cmd,
 
 944        "set metric <+/-metric>",
 
 946        "Metric value for destination routing protocol\n"
 
 947        "Add or subtract metric\n")
 
 949 DEFUN (no_set_metric,
 
 954        "Metric value for destination routing protocol\n")
 
 957     return rip_route_set_delete (vty, vty->index, "metric", NULL);
 
 959   return rip_route_set_delete (vty, vty->index, "metric", argv[0]);
 
 962 ALIAS (no_set_metric,
 
 963        no_set_metric_val_cmd,
 
 964        "no set metric <0-4294967295>",
 
 967        "Metric value for destination routing protocol\n"
 
 970 ALIAS (no_set_metric,
 
 971        no_set_metric_addsub_cmd,
 
 972        "no set metric <+/-metric>",
 
 975        "Metric value for destination routing protocol\n"
 
 976        "Add or subtract metric\n")
 
 978 DEFUN (set_ip_nexthop,
 
 980        "set ip next-hop A.B.C.D",
 
 984        "IP address of next hop\n")
 
 989   ret = str2sockunion (argv[0], &su);
 
 992       vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE);
 
 996   return rip_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
 
 999 DEFUN (no_set_ip_nexthop,
 
1000        no_set_ip_nexthop_cmd,
 
1001        "no set ip next-hop",
 
1005        "Next hop address\n")
 
1008     return rip_route_set_delete (vty, vty->index, "ip next-hop", NULL);
 
1010   return rip_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
 
1013 ALIAS (no_set_ip_nexthop,
 
1014        no_set_ip_nexthop_val_cmd,
 
1015        "no set ip next-hop A.B.C.D",
 
1019        "Next hop address\n"
 
1020        "IP address of next hop\n")
 
1024        "set tag <1-4294967295>",
 
1026        "Tag value for routing protocol\n"
 
1029   return rip_route_set_add (vty, vty->index, "tag", argv[0]);
 
1037        "Tag value for routing protocol\n")
 
1040     return rip_route_set_delete (vty, vty->index, "tag", NULL);
 
1042   return rip_route_set_delete (vty, vty->index, "tag", argv[0]);
 
1047        "no set tag <1-4294967295>",
 
1050        "Tag value for routing protocol\n"
 
1054 rip_route_map_reset ()
 
1059 /* Route-map init */
 
1061 rip_route_map_init ()
 
1064   route_map_init_vty ();
 
1065   route_map_add_hook (rip_route_map_update);
 
1066   route_map_delete_hook (rip_route_map_update);
 
1068   route_map_install_match (&route_match_metric_cmd);
 
1069   route_map_install_match (&route_match_interface_cmd);
 
1070   route_map_install_match (&route_match_ip_next_hop_cmd);
 
1071   route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
 
1072   route_map_install_match (&route_match_ip_address_cmd);
 
1073   route_map_install_match (&route_match_ip_address_prefix_list_cmd);
 
1074   route_map_install_match (&route_match_tag_cmd);
 
1076   route_map_install_set (&route_set_metric_cmd);
 
1077   route_map_install_set (&route_set_ip_nexthop_cmd);
 
1078   route_map_install_set (&route_set_tag_cmd);
 
1080   install_element (RMAP_NODE, &match_metric_cmd);
 
1081   install_element (RMAP_NODE, &no_match_metric_cmd);
 
1082   install_element (RMAP_NODE, &no_match_metric_val_cmd);
 
1083   install_element (RMAP_NODE, &match_interface_cmd);
 
1084   install_element (RMAP_NODE, &no_match_interface_cmd);
 
1085   install_element (RMAP_NODE, &no_match_interface_val_cmd);
 
1086   install_element (RMAP_NODE, &match_ip_next_hop_cmd);
 
1087   install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
 
1088   install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
 
1089   install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
 
1090   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
 
1091   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
 
1092   install_element (RMAP_NODE, &match_ip_address_cmd);
 
1093   install_element (RMAP_NODE, &no_match_ip_address_cmd);
 
1094   install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
 
1095   install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
 
1096   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
 
1097   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
 
1098   install_element (RMAP_NODE, &match_tag_cmd);
 
1099   install_element (RMAP_NODE, &no_match_tag_cmd);
 
1100   install_element (RMAP_NODE, &no_match_tag_val_cmd);
 
1102   install_element (RMAP_NODE, &set_metric_cmd);
 
1103   install_element (RMAP_NODE, &set_metric_addsub_cmd);
 
1104   install_element (RMAP_NODE, &no_set_metric_cmd);
 
1105   install_element (RMAP_NODE, &no_set_metric_val_cmd);
 
1106   install_element (RMAP_NODE, &no_set_metric_addsub_cmd);
 
1107   install_element (RMAP_NODE, &set_ip_nexthop_cmd);
 
1108   install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
 
1109   install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
 
1110   install_element (RMAP_NODE, &set_tag_cmd);
 
1111   install_element (RMAP_NODE, &no_set_tag_cmd);
 
1112   install_element (RMAP_NODE, &no_set_tag_val_cmd);