2  * Copyright (C) 1999 Kunihiro Ishiguro
 
   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
 
  29 #include "sockunion.h"
 
  31 #include "ripngd/ripngd.h"
 
  33 struct rip_metric_modifier
 
  47 ripng_route_match_add (struct vty *vty, struct route_map_index *index,
 
  48                        const char *command, const char *arg)
 
  52   ret = route_map_add_match (index, command, arg);
 
  57         case RMAP_RULE_MISSING:
 
  58           vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
 
  60         case RMAP_COMPILE_ERROR:
 
  61           vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
 
  69 ripng_route_match_delete (struct vty *vty, struct route_map_index *index,
 
  70                           const char *command, const char *arg)
 
  74   ret = route_map_delete_match (index, command, arg);
 
  79         case RMAP_RULE_MISSING:
 
  80           vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
 
  82         case RMAP_COMPILE_ERROR:
 
  83           vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
 
  91 ripng_route_set_add (struct vty *vty, struct route_map_index *index,
 
  92                      const char *command, const char *arg)
 
  96   ret = route_map_add_set (index, command, arg);
 
 101         case RMAP_RULE_MISSING:
 
 102           vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
 
 104         case RMAP_COMPILE_ERROR:
 
 105           vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
 
 113 ripng_route_set_delete (struct vty *vty, struct route_map_index *index,
 
 114                         const char *command, const char *arg)
 
 118   ret = route_map_delete_set (index, command, arg);
 
 123         case RMAP_RULE_MISSING:
 
 124           vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
 
 126         case RMAP_COMPILE_ERROR:
 
 127           vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
 
 134 /* `match metric METRIC' */
 
 135 /* Match function return 1 if match is success else return zero. */
 
 136 static route_map_result_t
 
 137 route_match_metric (void *rule, struct prefix *prefix, 
 
 138                     route_map_object_t type, void *object)
 
 141   struct ripng_info *rinfo;
 
 143   if (type == RMAP_RIPNG)
 
 148       if (rinfo->metric == *metric)
 
 156 /* Route map `match metric' match statement. `arg' is METRIC value */
 
 158 route_match_metric_compile (const char *arg)
 
 162   metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
 
 163   *metric = atoi (arg);
 
 168   XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
 
 172 /* Free route map's compiled `match metric' value. */
 
 174 route_match_metric_free (void *rule)
 
 176   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 179 /* Route map commands for metric matching. */
 
 180 static struct route_map_rule_cmd route_match_metric_cmd =
 
 184   route_match_metric_compile,
 
 185   route_match_metric_free
 
 188 /* `match interface IFNAME' */
 
 189 /* Match function return 1 if match is success else return zero. */
 
 190 static route_map_result_t
 
 191 route_match_interface (void *rule, struct prefix *prefix,
 
 192                        route_map_object_t type, void *object)
 
 194   struct ripng_info *rinfo;
 
 195   struct interface *ifp;
 
 198   if (type == RMAP_RIPNG)
 
 201       ifp = if_lookup_by_name(ifname);
 
 208       if (rinfo->ifindex == ifp->ifindex)
 
 216 /* Route map `match interface' match statement. `arg' is IFNAME value */
 
 218 route_match_interface_compile (const char *arg)
 
 220   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 224 route_match_interface_free (void *rule)
 
 226   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 229 static struct route_map_rule_cmd route_match_interface_cmd =
 
 232   route_match_interface,
 
 233   route_match_interface_compile,
 
 234   route_match_interface_free
 
 237 /* `match tag TAG' */
 
 238 /* Match function return 1 if match is success else return zero. */
 
 239 static route_map_result_t
 
 240 route_match_tag (void *rule, struct prefix *prefix, 
 
 241                     route_map_object_t type, void *object)
 
 244   struct ripng_info *rinfo;
 
 246   if (type == RMAP_RIPNG)
 
 251       /* The information stored by rinfo is host ordered. */
 
 252       if (rinfo->tag == *tag)
 
 260 static struct route_map_rule_cmd route_match_tag_cmd =
 
 264   route_map_rule_tag_compile,
 
 265   route_map_rule_tag_free,
 
 268 /* `set metric METRIC' */
 
 270 /* Set metric to attribute. */
 
 271 static route_map_result_t
 
 272 route_set_metric (void *rule, struct prefix *prefix, 
 
 273                   route_map_object_t type, void *object)
 
 275   if (type == RMAP_RIPNG)
 
 277       struct rip_metric_modifier *mod;
 
 278       struct ripng_info *rinfo;
 
 283       if (mod->type == metric_increment)
 
 284         rinfo->metric_out += mod->metric;
 
 285       else if (mod->type == metric_decrement)
 
 286         rinfo->metric_out-= mod->metric;
 
 287       else if (mod->type == metric_absolute)
 
 288         rinfo->metric_out = mod->metric;
 
 290       if (rinfo->metric_out < 1)
 
 291         rinfo->metric_out = 1;
 
 292       if (rinfo->metric_out > RIPNG_METRIC_INFINITY)
 
 293         rinfo->metric_out = RIPNG_METRIC_INFINITY;
 
 295       rinfo->metric_set = 1;
 
 300 /* set metric compilation. */
 
 302 route_set_metric_compile (const char *arg)
 
 309   struct rip_metric_modifier *mod;
 
 317   /* Examine first character. */
 
 320       type = metric_increment;
 
 323   else if (arg[0] == '-')
 
 325       type = metric_decrement;
 
 329     type = metric_absolute;
 
 331   /* Check beginning with digit string. */
 
 332   if (*pnt < '0' || *pnt > '9')
 
 335   /* Convert string to integer. */
 
 336   metric = strtol (pnt, &endptr, 10);
 
 338   if (metric == LONG_MAX || *endptr != '\0')
 
 340   /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
 
 341   /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
 
 345   mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, 
 
 346                  sizeof (struct rip_metric_modifier));
 
 348   mod->metric = metric;
 
 353 /* Free route map's compiled `set metric' value. */
 
 355 route_set_metric_free (void *rule)
 
 357   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 360 static struct route_map_rule_cmd route_set_metric_cmd = 
 
 364   route_set_metric_compile,
 
 365   route_set_metric_free,
 
 368 /* `set ipv6 next-hop local IP_ADDRESS' */
 
 370 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 
 371 static route_map_result_t
 
 372 route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, 
 
 373                       route_map_object_t type, void *object)
 
 375   struct in6_addr *address;
 
 376   struct ripng_info *rinfo;
 
 378   if(type == RMAP_RIPNG)
 
 380       /* Fetch routemap's rule information. */
 
 384       /* Set next hop value. */ 
 
 385       rinfo->nexthop_out = *address;
 
 391 /* Route map `ipv6 nexthop local' compile function.  Given string is converted
 
 392    to struct in6_addr structure. */
 
 394 route_set_ipv6_nexthop_local_compile (const char *arg)
 
 397   struct in6_addr *address;
 
 399   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
 
 401   ret = inet_pton (AF_INET6, arg, address);
 
 405       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
 
 412 /* Free route map's compiled `ipv6 nexthop local' value. */
 
 414 route_set_ipv6_nexthop_local_free (void *rule)
 
 416   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 419 /* Route map commands for ipv6 nexthop local set. */
 
 420 static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
 
 422   "ipv6 next-hop local",
 
 423   route_set_ipv6_nexthop_local,
 
 424   route_set_ipv6_nexthop_local_compile,
 
 425   route_set_ipv6_nexthop_local_free
 
 430 /* Set tag to object.  ojbect must be pointer to struct attr. */
 
 431 static route_map_result_t
 
 432 route_set_tag (void *rule, struct prefix *prefix, 
 
 433                       route_map_object_t type, void *object)
 
 436   struct ripng_info *rinfo;
 
 438   if(type == RMAP_RIPNG)
 
 440       /* Fetch routemap's rule information. */
 
 444       /* Set next hop value. */ 
 
 445       rinfo->tag_out = *tag;
 
 451 /* Route map commands for tag set. */
 
 452 static struct route_map_rule_cmd route_set_tag_cmd =
 
 456   route_map_rule_tag_compile,
 
 457   route_map_rule_tag_free
 
 460 #define MATCH_STR "Match values from routing table\n"
 
 461 #define SET_STR "Set values in destination routing protocol\n"
 
 465        "match metric <0-4294967295>",
 
 467        "Match metric of route\n"
 
 470   return ripng_route_match_add (vty, vty->index, "metric", argv[0]);
 
 473 DEFUN (no_match_metric,
 
 478        "Match metric of route\n")
 
 481     return ripng_route_match_delete (vty, vty->index, "metric", NULL);
 
 483   return ripng_route_match_delete (vty, vty->index, "metric", argv[0]);
 
 486 ALIAS (no_match_metric,
 
 487        no_match_metric_val_cmd,
 
 488        "no match metric <0-4294967295>",
 
 491        "Match metric of route\n"
 
 494 DEFUN (match_interface,
 
 496        "match interface WORD",
 
 498        "Match first hop interface of route\n"
 
 501   return ripng_route_match_add (vty, vty->index, "interface", argv[0]);
 
 504 DEFUN (no_match_interface,
 
 505        no_match_interface_cmd,
 
 506        "no match interface",
 
 509        "Match first hop interface of route\n")
 
 512     return ripng_route_match_delete (vty, vty->index, "interface", NULL);
 
 514   return ripng_route_match_delete (vty, vty->index, "interface", argv[0]);
 
 517 ALIAS (no_match_interface,
 
 518        no_match_interface_val_cmd,
 
 519        "no match interface WORD",
 
 522        "Match first hop interface of route\n"
 
 527        "match tag <1-4294967295>",
 
 529        "Match tag of route\n"
 
 532   return ripng_route_match_add (vty, vty->index, "tag", argv[0]);
 
 540        "Match tag of route\n")
 
 543     return ripng_route_match_delete (vty, vty->index, "tag", NULL);
 
 545   return ripng_route_match_delete (vty, vty->index, "tag", argv[0]);
 
 549        no_match_tag_val_cmd,
 
 550        "no match tag <1-4294967295>",
 
 553        "Match tag of route\n"
 
 560        "set metric <0-4294967295>",
 
 562        "Metric value for destination routing protocol\n"
 
 565   return ripng_route_set_add (vty, vty->index, "metric", argv[0]);
 
 568 DEFUN (no_set_metric,
 
 573        "Metric value for destination routing protocol\n")
 
 576     return ripng_route_set_delete (vty, vty->index, "metric", NULL);
 
 578   return ripng_route_set_delete (vty, vty->index, "metric", argv[0]);
 
 581 ALIAS (no_set_metric,
 
 582        no_set_metric_val_cmd,
 
 583        "no set metric <0-4294967295>",
 
 586        "Metric value for destination routing protocol\n"
 
 589 DEFUN (set_ipv6_nexthop_local,
 
 590        set_ipv6_nexthop_local_cmd,
 
 591        "set ipv6 next-hop local X:X::X:X",
 
 594        "IPv6 next-hop address\n"
 
 595        "IPv6 local address\n"
 
 596        "IPv6 address of next hop\n")
 
 601   ret = str2sockunion (argv[0], &su);
 
 604       vty_out (vty, "%% Malformed next-hop local address%s", VTY_NEWLINE);
 
 608   return ripng_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
 
 611 DEFUN (no_set_ipv6_nexthop_local,
 
 612        no_set_ipv6_nexthop_local_cmd,
 
 613        "no set ipv6 next-hop local",
 
 617        "IPv6 next-hop address\n"
 
 618        "IPv6 local address\n")
 
 621     return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
 
 623   return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
 
 626 ALIAS (no_set_ipv6_nexthop_local,
 
 627        no_set_ipv6_nexthop_local_val_cmd,
 
 628        "no set ipv6 next-hop local X:X::X:X",
 
 632        "IPv6 next-hop address\n"
 
 633        "IPv6 local address\n"
 
 634        "IPv6 address of next hop\n")
 
 638        "set tag <1-4294967295>",
 
 640        "Tag value for routing protocol\n"
 
 643   return ripng_route_set_add (vty, vty->index, "tag", argv[0]);
 
 651        "Tag value for routing protocol\n")
 
 654     return ripng_route_set_delete (vty, vty->index, "tag", NULL);
 
 656   return ripng_route_set_delete (vty, vty->index, "tag", argv[0]);
 
 661        "no set tag <1-4294967295>",
 
 664        "Tag value for routing protocol\n"
 
 668 ripng_route_map_reset ()
 
 675 ripng_route_map_init ()
 
 678   route_map_init_vty ();
 
 680   route_map_install_match (&route_match_metric_cmd);
 
 681   route_map_install_match (&route_match_interface_cmd);
 
 682   route_map_install_match (&route_match_tag_cmd);
 
 684   route_map_install_set (&route_set_metric_cmd);
 
 685   route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
 
 686   route_map_install_set (&route_set_tag_cmd);
 
 688   install_element (RMAP_NODE, &match_metric_cmd);
 
 689   install_element (RMAP_NODE, &no_match_metric_cmd);
 
 690   install_element (RMAP_NODE, &no_match_metric_val_cmd);
 
 691   install_element (RMAP_NODE, &match_interface_cmd);
 
 692   install_element (RMAP_NODE, &no_match_interface_cmd);
 
 693   install_element (RMAP_NODE, &no_match_interface_val_cmd);
 
 694   install_element (RMAP_NODE, &match_tag_cmd);
 
 695   install_element (RMAP_NODE, &no_match_tag_cmd);
 
 696   install_element (RMAP_NODE, &no_match_tag_val_cmd);
 
 698   install_element (RMAP_NODE, &set_metric_cmd);
 
 699   install_element (RMAP_NODE, &no_set_metric_cmd);
 
 700   install_element (RMAP_NODE, &no_set_metric_val_cmd);
 
 701   install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
 
 702   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
 
 703   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
 
 704   install_element (RMAP_NODE, &set_tag_cmd);
 
 705   install_element (RMAP_NODE, &no_set_tag_cmd);
 
 706   install_element (RMAP_NODE, &no_set_tag_val_cmd);