File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ripd / rip_routemap.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 7 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /* RIPv2 routemap.
    2:  * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
    3:  * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
    4:  *
    5:  * This file is part of GNU Zebra.
    6:  *
    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
   10:  * later version.
   11:  *
   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.
   16:  *
   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
   20:  * 02111-1307, USA.  
   21:  */
   22: 
   23: #include <zebra.h>
   24: 
   25: #include "memory.h"
   26: #include "prefix.h"
   27: #include "routemap.h"
   28: #include "command.h"
   29: #include "filter.h"
   30: #include "log.h"
   31: #include "sockunion.h"		/* for inet_aton () */
   32: #include "plist.h"
   33: 
   34: #include "ripd/ripd.h"
   35: 
   36: struct rip_metric_modifier
   37: {
   38:   enum 
   39:   {
   40:     metric_increment,
   41:     metric_decrement,
   42:     metric_absolute
   43:   } type;
   44: 
   45:   u_char metric;
   46: };
   47: 
   48: /* Add rip route map rule. */
   49: static int
   50: rip_route_match_add (struct vty *vty, struct route_map_index *index,
   51: 		     const char *command, const char *arg)
   52: {
   53:   int ret;
   54: 
   55:   ret = route_map_add_match (index, command, arg);
   56:   if (ret)
   57:     {
   58:       switch (ret)
   59: 	{
   60: 	case RMAP_RULE_MISSING:
   61: 	  vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
   62: 	  return CMD_WARNING;
   63: 	case RMAP_COMPILE_ERROR:
   64: 	  vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
   65: 	  return CMD_WARNING;
   66: 	}
   67:     }
   68:   return CMD_SUCCESS;
   69: }
   70: 
   71: /* Delete rip route map rule. */
   72: static int
   73: rip_route_match_delete (struct vty *vty, struct route_map_index *index,
   74: 			const char *command, const char *arg)
   75: {
   76:   int ret;
   77: 
   78:   ret = route_map_delete_match (index, command, arg);
   79:   if (ret)
   80:     {
   81:       switch (ret)
   82: 	{
   83: 	case RMAP_RULE_MISSING:
   84: 	  vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
   85: 	  return CMD_WARNING;
   86: 	case RMAP_COMPILE_ERROR:
   87: 	  vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
   88: 	  return CMD_WARNING;
   89: 	}
   90:     }
   91:   return CMD_SUCCESS;
   92: }
   93: 
   94: /* Add rip route map rule. */
   95: static int
   96: rip_route_set_add (struct vty *vty, struct route_map_index *index,
   97: 		   const char *command, const char *arg)
   98: {
   99:   int ret;
  100: 
  101:   ret = route_map_add_set (index, command, arg);
  102:   if (ret)
  103:     {
  104:       switch (ret)
  105: 	{
  106: 	case RMAP_RULE_MISSING:
  107: 	  vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  108: 	  return CMD_WARNING;
  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, "%% Argument is malformed.%s", VTY_NEWLINE);
  116: 	     return CMD_WARNING;
  117: 	  }
  118: 	}
  119:     }
  120:   return CMD_SUCCESS;
  121: }
  122: 
  123: /* Delete rip route map rule. */
  124: static int
  125: rip_route_set_delete (struct vty *vty, struct route_map_index *index,
  126: 		      const char *command, const char *arg)
  127: {
  128:   int ret;
  129: 
  130:   ret = route_map_delete_set (index, command, arg);
  131:   if (ret)
  132:     {
  133:       switch (ret)
  134: 	{
  135: 	case RMAP_RULE_MISSING:
  136: 	  vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  137: 	  return CMD_WARNING;
  138: 	case RMAP_COMPILE_ERROR:
  139: 	  vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  140: 	  return CMD_WARNING;
  141: 	}
  142:     }
  143:   return CMD_SUCCESS;
  144: }
  145: 
  146: /* Hook function for updating route_map assignment. */
  147: /* ARGSUSED */
  148: static void
  149: rip_route_map_update (const char *notused)
  150: {
  151:   int i;
  152: 
  153:   if (rip) 
  154:     {
  155:       for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
  156: 	{
  157: 	  if (rip->route_map[i].name)
  158: 	    rip->route_map[i].map = 
  159: 	      route_map_lookup_by_name (rip->route_map[i].name);
  160: 	}
  161:     }
  162: }
  163: 
  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)
  169: {
  170:   u_int32_t *metric;
  171:   u_int32_t  check;
  172:   struct rip_info *rinfo;
  173: 
  174:   if (type == RMAP_RIP)
  175:     {
  176:       metric = rule;
  177:       rinfo = object;
  178:     
  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 :
  182:                                          rinfo->metric;
  183:       if (check == *metric)
  184: 	return RMAP_MATCH;
  185:       else
  186: 	return RMAP_NOMATCH;
  187:     }
  188:   return RMAP_NOMATCH;
  189: }
  190: 
  191: /* Route map `match metric' match statement. `arg' is METRIC value */
  192: static void *
  193: route_match_metric_compile (const char *arg)
  194: {
  195:   u_int32_t *metric;
  196: 
  197:   metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
  198:   *metric = atoi (arg);
  199: 
  200:   if(*metric > 0)
  201:     return metric;
  202: 
  203:   XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
  204:   return NULL;
  205: }
  206: 
  207: /* Free route map's compiled `match metric' value. */
  208: static void
  209: route_match_metric_free (void *rule)
  210: {
  211:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  212: }
  213: 
  214: /* Route map commands for metric matching. */
  215: struct route_map_rule_cmd route_match_metric_cmd =
  216: {
  217:   "metric",
  218:   route_match_metric,
  219:   route_match_metric_compile,
  220:   route_match_metric_free
  221: };
  222: 
  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)
  228: {
  229:   struct rip_info *rinfo;
  230:   struct interface *ifp;
  231:   char *ifname;
  232: 
  233:   if (type == RMAP_RIP)
  234:     {
  235:       ifname = rule;
  236:       ifp = if_lookup_by_name(ifname);
  237: 
  238:       if (!ifp)
  239: 	return RMAP_NOMATCH;
  240: 
  241:       rinfo = object;
  242: 
  243:       if (rinfo->ifindex_out == ifp->ifindex || rinfo->ifindex == ifp->ifindex)
  244: 	return RMAP_MATCH;
  245:       else
  246: 	return RMAP_NOMATCH;
  247:     }
  248:   return RMAP_NOMATCH;
  249: }
  250: 
  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? */
  253: static void *
  254: route_match_interface_compile (const char *arg)
  255: {
  256:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  257: }
  258: 
  259: /* Free route map's compiled `match interface' value. */
  260: static void
  261: route_match_interface_free (void *rule)
  262: {
  263:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  264: }
  265: 
  266: /* Route map commands for interface matching. */
  267: struct route_map_rule_cmd route_match_interface_cmd =
  268: {
  269:   "interface",
  270:   route_match_interface,
  271:   route_match_interface_compile,
  272:   route_match_interface_free
  273: };
  274: 
  275: /* `match ip next-hop IP_ACCESS_LIST' */
  276: 
  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)
  281: {
  282:   struct access_list *alist;
  283:   struct rip_info *rinfo;
  284:   struct prefix_ipv4 p;
  285: 
  286:   if (type == RMAP_RIP)
  287:     {
  288:       rinfo = object;
  289:       p.family = AF_INET;
  290:       p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;
  291:       p.prefixlen = IPV4_MAX_BITLEN;
  292: 
  293:       alist = access_list_lookup (AFI_IP, (char *) rule);
  294:       if (alist == NULL)
  295: 	return RMAP_NOMATCH;
  296: 
  297:       return (access_list_apply (alist, &p) == FILTER_DENY ?
  298: 	      RMAP_NOMATCH : RMAP_MATCH);
  299:     }
  300:   return RMAP_NOMATCH;
  301: }
  302: 
  303: /* Route map `ip next-hop' match statement.  `arg' should be
  304:    access-list name. */
  305: static void *
  306: route_match_ip_next_hop_compile (const char *arg)
  307: {
  308:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  309: }
  310: 
  311: /* Free route map's compiled `. */
  312: static void
  313: route_match_ip_next_hop_free (void *rule)
  314: {
  315:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  316: }
  317: 
  318: /* Route map commands for ip next-hop matching. */
  319: static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
  320: {
  321:   "ip next-hop",
  322:   route_match_ip_next_hop,
  323:   route_match_ip_next_hop_compile,
  324:   route_match_ip_next_hop_free
  325: };
  326: 
  327: /* `match ip next-hop prefix-list PREFIX_LIST' */
  328: 
  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)
  332: {
  333:   struct prefix_list *plist;
  334:   struct rip_info *rinfo;
  335:   struct prefix_ipv4 p;
  336: 
  337:   if (type == RMAP_RIP)
  338:     {
  339:       rinfo = object;
  340:       p.family = AF_INET;
  341:       p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;
  342:       p.prefixlen = IPV4_MAX_BITLEN;
  343: 
  344:       plist = prefix_list_lookup (AFI_IP, (char *) rule);
  345:       if (plist == NULL)
  346:         return RMAP_NOMATCH;
  347: 
  348:       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
  349:               RMAP_NOMATCH : RMAP_MATCH);
  350:     }
  351:   return RMAP_NOMATCH;
  352: }
  353: 
  354: static void *
  355: route_match_ip_next_hop_prefix_list_compile (const char *arg)
  356: {
  357:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  358: }
  359: 
  360: static void
  361: route_match_ip_next_hop_prefix_list_free (void *rule)
  362: {
  363:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  364: }
  365: 
  366: static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
  367: {
  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
  372: };
  373: 
  374: /* `match ip address IP_ACCESS_LIST' */
  375: 
  376: /* Match function should return 1 if match is success else return
  377:    zero. */
  378: static route_map_result_t
  379: route_match_ip_address (void *rule, struct prefix *prefix, 
  380: 			route_map_object_t type, void *object)
  381: {
  382:   struct access_list *alist;
  383: 
  384:   if (type == RMAP_RIP)
  385:     {
  386:       alist = access_list_lookup (AFI_IP, (char *) rule);
  387:       if (alist == NULL)
  388: 	return RMAP_NOMATCH;
  389:     
  390:       return (access_list_apply (alist, prefix) == FILTER_DENY ?
  391: 	      RMAP_NOMATCH : RMAP_MATCH);
  392:     }
  393:   return RMAP_NOMATCH;
  394: }
  395: 
  396: /* Route map `ip address' match statement.  `arg' should be
  397:    access-list name. */
  398: static void *
  399: route_match_ip_address_compile (const char *arg)
  400: {
  401:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  402: }
  403: 
  404: /* Free route map's compiled `ip address' value. */
  405: static void
  406: route_match_ip_address_free (void *rule)
  407: {
  408:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  409: }
  410: 
  411: /* Route map commands for ip address matching. */
  412: static struct route_map_rule_cmd route_match_ip_address_cmd =
  413: {
  414:   "ip address",
  415:   route_match_ip_address,
  416:   route_match_ip_address_compile,
  417:   route_match_ip_address_free
  418: };
  419: 
  420: /* `match ip address prefix-list PREFIX_LIST' */
  421: 
  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)
  425: {
  426:   struct prefix_list *plist;
  427: 
  428:   if (type == RMAP_RIP)
  429:     {
  430:       plist = prefix_list_lookup (AFI_IP, (char *) rule);
  431:       if (plist == NULL)
  432: 	return RMAP_NOMATCH;
  433:     
  434:       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  435: 	      RMAP_NOMATCH : RMAP_MATCH);
  436:     }
  437:   return RMAP_NOMATCH;
  438: }
  439: 
  440: static void *
  441: route_match_ip_address_prefix_list_compile (const char *arg)
  442: {
  443:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  444: }
  445: 
  446: static void
  447: route_match_ip_address_prefix_list_free (void *rule)
  448: {
  449:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  450: }
  451: 
  452: static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
  453: {
  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
  458: };
  459: 
  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)
  465: {
  466:   u_short *tag;
  467:   struct rip_info *rinfo;
  468: 
  469:   if (type == RMAP_RIP)
  470:     {
  471:       tag = rule;
  472:       rinfo = object;
  473: 
  474:       /* The information stored by rinfo is host ordered. */
  475:       if (rinfo->tag == *tag)
  476: 	return RMAP_MATCH;
  477:       else
  478: 	return RMAP_NOMATCH;
  479:     }
  480:   return RMAP_NOMATCH;
  481: }
  482: 
  483: /* Route map `match tag' match statement. `arg' is TAG value */
  484: static void *
  485: route_match_tag_compile (const char *arg)
  486: {
  487:   u_short *tag;
  488: 
  489:   tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
  490:   *tag = atoi (arg);
  491: 
  492:   return tag;
  493: }
  494: 
  495: /* Free route map's compiled `match tag' value. */
  496: static void
  497: route_match_tag_free (void *rule)
  498: {
  499:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  500: }
  501: 
  502: /* Route map commands for tag matching. */
  503: struct route_map_rule_cmd route_match_tag_cmd =
  504: {
  505:   "tag",
  506:   route_match_tag,
  507:   route_match_tag_compile,
  508:   route_match_tag_free
  509: };
  510: 
  511: /* `set metric METRIC' */
  512: 
  513: /* Set metric to attribute. */
  514: static route_map_result_t
  515: route_set_metric (void *rule, struct prefix *prefix, 
  516: 		  route_map_object_t type, void *object)
  517: {
  518:   if (type == RMAP_RIP)
  519:     {
  520:       struct rip_metric_modifier *mod;
  521:       struct rip_info *rinfo;
  522: 
  523:       mod = rule;
  524:       rinfo = object;
  525: 
  526:       if (mod->type == metric_increment)
  527: 	rinfo->metric_out += mod->metric;
  528:       else if (mod->type == metric_decrement)
  529: 	rinfo->metric_out -= mod->metric;
  530:       else if (mod->type == metric_absolute)
  531: 	rinfo->metric_out = mod->metric;
  532: 
  533:       if ((signed int)rinfo->metric_out < 1)
  534: 	rinfo->metric_out = 1;
  535:       if (rinfo->metric_out > RIP_METRIC_INFINITY)
  536: 	rinfo->metric_out = RIP_METRIC_INFINITY;
  537: 
  538:       rinfo->metric_set = 1;
  539:     }
  540:   return RMAP_OKAY;
  541: }
  542: 
  543: /* set metric compilation. */
  544: static void *
  545: route_set_metric_compile (const char *arg)
  546: {
  547:   int len;
  548:   const char *pnt;
  549:   int type;
  550:   long metric;
  551:   char *endptr = NULL;
  552:   struct rip_metric_modifier *mod;
  553: 
  554:   len = strlen (arg);
  555:   pnt = arg;
  556: 
  557:   if (len == 0)
  558:     return NULL;
  559: 
  560:   /* Examine first character. */
  561:   if (arg[0] == '+')
  562:     {
  563:       type = metric_increment;
  564:       pnt++;
  565:     }
  566:   else if (arg[0] == '-')
  567:     {
  568:       type = metric_decrement;
  569:       pnt++;
  570:     }
  571:   else
  572:     type = metric_absolute;
  573: 
  574:   /* Check beginning with digit string. */
  575:   if (*pnt < '0' || *pnt > '9')
  576:     return NULL;
  577: 
  578:   /* Convert string to integer. */
  579:   metric = strtol (pnt, &endptr, 10);
  580: 
  581:   if (metric == LONG_MAX || *endptr != '\0')
  582:     return NULL;
  583:   if (metric < 0 || metric > RIP_METRIC_INFINITY)
  584:     return NULL;
  585: 
  586:   mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, 
  587: 		 sizeof (struct rip_metric_modifier));
  588:   mod->type = type;
  589:   mod->metric = metric;
  590: 
  591:   return mod;
  592: }
  593: 
  594: /* Free route map's compiled `set metric' value. */
  595: static void
  596: route_set_metric_free (void *rule)
  597: {
  598:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  599: }
  600: 
  601: /* Set metric rule structure. */
  602: static struct route_map_rule_cmd route_set_metric_cmd = 
  603: {
  604:   "metric",
  605:   route_set_metric,
  606:   route_set_metric_compile,
  607:   route_set_metric_free,
  608: };
  609: 
  610: /* `set ip next-hop IP_ADDRESS' */
  611: 
  612: /* Set nexthop to object.  ojbect must be pointer to struct attr. */
  613: static route_map_result_t
  614: route_set_ip_nexthop (void *rule, struct prefix *prefix, 
  615: 		      route_map_object_t type, void *object)
  616: {
  617:   struct in_addr *address;
  618:   struct rip_info *rinfo;
  619: 
  620:   if(type == RMAP_RIP)
  621:     {
  622:       /* Fetch routemap's rule information. */
  623:       address = rule;
  624:       rinfo = object;
  625:     
  626:       /* Set next hop value. */ 
  627:       rinfo->nexthop_out = *address;
  628:     }
  629: 
  630:   return RMAP_OKAY;
  631: }
  632: 
  633: /* Route map `ip nexthop' compile function.  Given string is converted
  634:    to struct in_addr structure. */
  635: static void *
  636: route_set_ip_nexthop_compile (const char *arg)
  637: {
  638:   int ret;
  639:   struct in_addr *address;
  640: 
  641:   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
  642: 
  643:   ret = inet_aton (arg, address);
  644: 
  645:   if (ret == 0)
  646:     {
  647:       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  648:       return NULL;
  649:     }
  650: 
  651:   return address;
  652: }
  653: 
  654: /* Free route map's compiled `ip nexthop' value. */
  655: static void
  656: route_set_ip_nexthop_free (void *rule)
  657: {
  658:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  659: }
  660: 
  661: /* Route map commands for ip nexthop set. */
  662: static struct route_map_rule_cmd route_set_ip_nexthop_cmd =
  663: {
  664:   "ip next-hop",
  665:   route_set_ip_nexthop,
  666:   route_set_ip_nexthop_compile,
  667:   route_set_ip_nexthop_free
  668: };
  669: 
  670: /* `set tag TAG' */
  671: 
  672: /* Set tag to object.  ojbect must be pointer to struct attr. */
  673: static route_map_result_t
  674: route_set_tag (void *rule, struct prefix *prefix, 
  675: 		      route_map_object_t type, void *object)
  676: {
  677:   u_short *tag;
  678:   struct rip_info *rinfo;
  679: 
  680:   if(type == RMAP_RIP)
  681:     {
  682:       /* Fetch routemap's rule information. */
  683:       tag = rule;
  684:       rinfo = object;
  685:     
  686:       /* Set next hop value. */ 
  687:       rinfo->tag_out = *tag;
  688:     }
  689: 
  690:   return RMAP_OKAY;
  691: }
  692: 
  693: /* Route map `tag' compile function.  Given string is converted
  694:    to u_short. */
  695: static void *
  696: route_set_tag_compile (const char *arg)
  697: {
  698:   u_short *tag;
  699: 
  700:   tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
  701:   *tag = atoi (arg);
  702: 
  703:   return tag;
  704: }
  705: 
  706: /* Free route map's compiled `ip nexthop' value. */
  707: static void
  708: route_set_tag_free (void *rule)
  709: {
  710:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  711: }
  712: 
  713: /* Route map commands for tag set. */
  714: static struct route_map_rule_cmd route_set_tag_cmd =
  715: {
  716:   "tag",
  717:   route_set_tag,
  718:   route_set_tag_compile,
  719:   route_set_tag_free
  720: };
  721: 
  722: #define MATCH_STR "Match values from routing table\n"
  723: #define SET_STR "Set values in destination routing protocol\n"
  724: 
  725: DEFUN (match_metric, 
  726:        match_metric_cmd,
  727:        "match metric <0-4294967295>",
  728:        MATCH_STR
  729:        "Match metric of route\n"
  730:        "Metric value\n")
  731: {
  732:   return rip_route_match_add (vty, vty->index, "metric", argv[0]);
  733: }
  734: 
  735: DEFUN (no_match_metric,
  736:        no_match_metric_cmd,
  737:        "no match metric",
  738:        NO_STR
  739:        MATCH_STR
  740:        "Match metric of route\n")
  741: {
  742:   if (argc == 0)
  743:     return rip_route_match_delete (vty, vty->index, "metric", NULL);
  744: 
  745:   return rip_route_match_delete (vty, vty->index, "metric", argv[0]);
  746: }
  747: 
  748: ALIAS (no_match_metric,
  749:        no_match_metric_val_cmd,
  750:        "no match metric <0-4294967295>",
  751:        NO_STR
  752:        MATCH_STR
  753:        "Match metric of route\n"
  754:        "Metric value\n")
  755: 
  756: DEFUN (match_interface,
  757:        match_interface_cmd,
  758:        "match interface WORD",
  759:        MATCH_STR
  760:        "Match first hop interface of route\n"
  761:        "Interface name\n")
  762: {
  763:   return rip_route_match_add (vty, vty->index, "interface", argv[0]);
  764: }
  765: 
  766: DEFUN (no_match_interface,
  767:        no_match_interface_cmd,
  768:        "no match interface",
  769:        NO_STR
  770:        MATCH_STR
  771:        "Match first hop interface of route\n")
  772: {
  773:   if (argc == 0)
  774:     return rip_route_match_delete (vty, vty->index, "interface", NULL);
  775: 
  776:   return rip_route_match_delete (vty, vty->index, "interface", argv[0]);
  777: }
  778: 
  779: ALIAS (no_match_interface,
  780:        no_match_interface_val_cmd,
  781:        "no match interface WORD",
  782:        NO_STR
  783:        MATCH_STR
  784:        "Match first hop interface of route\n"
  785:        "Interface name\n")
  786: 
  787: DEFUN (match_ip_next_hop,
  788:        match_ip_next_hop_cmd,
  789:        "match ip next-hop (<1-199>|<1300-2699>|WORD)",
  790:        MATCH_STR
  791:        IP_STR
  792:        "Match next-hop address of route\n"
  793:        "IP access-list number\n"
  794:        "IP access-list number (expanded range)\n"
  795:        "IP Access-list name\n")
  796: {
  797:   return rip_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
  798: }
  799: 
  800: DEFUN (no_match_ip_next_hop,
  801:        no_match_ip_next_hop_cmd,
  802:        "no match ip next-hop",
  803:        NO_STR
  804:        MATCH_STR
  805:        IP_STR
  806:        "Match next-hop address of route\n")
  807: {
  808:   if (argc == 0)
  809:     return rip_route_match_delete (vty, vty->index, "ip next-hop", NULL);
  810: 
  811:   return rip_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
  812: }
  813: 
  814: ALIAS (no_match_ip_next_hop,
  815:        no_match_ip_next_hop_val_cmd,
  816:        "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
  817:        NO_STR
  818:        MATCH_STR
  819:        IP_STR
  820:        "Match next-hop address of route\n"
  821:        "IP access-list number\n"
  822:        "IP access-list number (expanded range)\n"
  823:        "IP Access-list name\n")
  824: 
  825: DEFUN (match_ip_next_hop_prefix_list,
  826:        match_ip_next_hop_prefix_list_cmd,
  827:        "match ip next-hop prefix-list WORD",
  828:        MATCH_STR
  829:        IP_STR
  830:        "Match next-hop address of route\n"
  831:        "Match entries of prefix-lists\n"
  832:        "IP prefix-list name\n")
  833: {
  834:   return rip_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  835: }
  836: 
  837: DEFUN (no_match_ip_next_hop_prefix_list,
  838:        no_match_ip_next_hop_prefix_list_cmd,
  839:        "no match ip next-hop prefix-list",
  840:        NO_STR
  841:        MATCH_STR
  842:        IP_STR
  843:        "Match next-hop address of route\n"
  844:        "Match entries of prefix-lists\n")
  845: {
  846:   if (argc == 0)
  847:     return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
  848: 
  849:   return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  850: }
  851: 
  852: ALIAS (no_match_ip_next_hop_prefix_list,
  853:        no_match_ip_next_hop_prefix_list_val_cmd,
  854:        "no match ip next-hop prefix-list WORD",
  855:        NO_STR
  856:        MATCH_STR
  857:        IP_STR
  858:        "Match next-hop address of route\n"
  859:        "Match entries of prefix-lists\n"
  860:        "IP prefix-list name\n")
  861: 
  862: DEFUN (match_ip_address,
  863:        match_ip_address_cmd,
  864:        "match ip address (<1-199>|<1300-2699>|WORD)",
  865:        MATCH_STR
  866:        IP_STR
  867:        "Match address of route\n"
  868:        "IP access-list number\n"
  869:        "IP access-list number (expanded range)\n"
  870:        "IP Access-list name\n")
  871: 
  872: {
  873:   return rip_route_match_add (vty, vty->index, "ip address", argv[0]);
  874: }
  875: 
  876: DEFUN (no_match_ip_address, 
  877:        no_match_ip_address_cmd,
  878:        "no match ip address",
  879:        NO_STR
  880:        MATCH_STR
  881:        IP_STR
  882:        "Match address of route\n")
  883: {
  884:   if (argc == 0)
  885:     return rip_route_match_delete (vty, vty->index, "ip address", NULL);
  886: 
  887:   return rip_route_match_delete (vty, vty->index, "ip address", argv[0]);
  888: }
  889: 
  890: ALIAS (no_match_ip_address,
  891:        no_match_ip_address_val_cmd,
  892:        "no match ip address (<1-199>|<1300-2699>|WORD)",
  893:        NO_STR
  894:        MATCH_STR
  895:        IP_STR
  896:        "Match address of route\n"
  897:        "IP access-list number\n"
  898:        "IP access-list number (expanded range)\n"
  899:        "IP Access-list name\n")
  900: 
  901: DEFUN (match_ip_address_prefix_list, 
  902:        match_ip_address_prefix_list_cmd,
  903:        "match ip address prefix-list WORD",
  904:        MATCH_STR
  905:        IP_STR
  906:        "Match address of route\n"
  907:        "Match entries of prefix-lists\n"
  908:        "IP prefix-list name\n")
  909: {
  910:   return rip_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
  911: }
  912: 
  913: DEFUN (no_match_ip_address_prefix_list,
  914:        no_match_ip_address_prefix_list_cmd,
  915:        "no match ip address prefix-list",
  916:        NO_STR
  917:        MATCH_STR
  918:        IP_STR
  919:        "Match address of route\n"
  920:        "Match entries of prefix-lists\n")
  921: {
  922:   if (argc == 0)
  923:     return rip_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
  924: 
  925:   return rip_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
  926: }
  927: 
  928: ALIAS (no_match_ip_address_prefix_list,
  929:        no_match_ip_address_prefix_list_val_cmd,
  930:        "no match ip address prefix-list WORD",
  931:        NO_STR
  932:        MATCH_STR
  933:        IP_STR
  934:        "Match address of route\n"
  935:        "Match entries of prefix-lists\n"
  936:        "IP prefix-list name\n")
  937: 
  938: DEFUN (match_tag, 
  939:        match_tag_cmd,
  940:        "match tag <0-65535>",
  941:        MATCH_STR
  942:        "Match tag of route\n"
  943:        "Metric value\n")
  944: {
  945:   return rip_route_match_add (vty, vty->index, "tag", argv[0]);
  946: }
  947: 
  948: DEFUN (no_match_tag,
  949:        no_match_tag_cmd,
  950:        "no match tag",
  951:        NO_STR
  952:        MATCH_STR
  953:        "Match tag of route\n")
  954: {
  955:   if (argc == 0)
  956:     return rip_route_match_delete (vty, vty->index, "tag", NULL);
  957: 
  958:   return rip_route_match_delete (vty, vty->index, "tag", argv[0]);
  959: }
  960: 
  961: ALIAS (no_match_tag,
  962:        no_match_tag_val_cmd,
  963:        "no match tag <0-65535>",
  964:        NO_STR
  965:        MATCH_STR
  966:        "Match tag of route\n"
  967:        "Metric value\n")
  968: 
  969: /* set functions */
  970: 
  971: DEFUN (set_metric,
  972:        set_metric_cmd,
  973:        "set metric <0-4294967295>",
  974:        SET_STR
  975:        "Metric value for destination routing protocol\n"
  976:        "Metric value\n")
  977: {
  978:   return rip_route_set_add (vty, vty->index, "metric", argv[0]);
  979: }
  980: 
  981: ALIAS (set_metric,
  982:        set_metric_addsub_cmd,
  983:        "set metric <+/-metric>",
  984:        SET_STR
  985:        "Metric value for destination routing protocol\n"
  986:        "Add or subtract metric\n")
  987: 
  988: DEFUN (no_set_metric,
  989:        no_set_metric_cmd,
  990:        "no set metric",
  991:        NO_STR
  992:        SET_STR
  993:        "Metric value for destination routing protocol\n")
  994: {
  995:   if (argc == 0)
  996:     return rip_route_set_delete (vty, vty->index, "metric", NULL);
  997: 
  998:   return rip_route_set_delete (vty, vty->index, "metric", argv[0]);
  999: }
 1000: 
 1001: ALIAS (no_set_metric,
 1002:        no_set_metric_val_cmd,
 1003:        "no set metric (<0-4294967295>|<+/-metric>)",
 1004:        NO_STR
 1005:        SET_STR
 1006:        "Metric value for destination routing protocol\n"
 1007:        "Metric value\n"
 1008:        "Add or subtract metric\n")
 1009: 
 1010: DEFUN (set_ip_nexthop,
 1011:        set_ip_nexthop_cmd,
 1012:        "set ip next-hop A.B.C.D",
 1013:        SET_STR
 1014:        IP_STR
 1015:        "Next hop address\n"
 1016:        "IP address of next hop\n")
 1017: {
 1018:   union sockunion su;
 1019:   int ret;
 1020: 
 1021:   ret = str2sockunion (argv[0], &su);
 1022:   if (ret < 0)
 1023:     {
 1024:       vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE);
 1025:       return CMD_WARNING;
 1026:     }
 1027: 
 1028:   return rip_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
 1029: }
 1030: 
 1031: DEFUN (no_set_ip_nexthop,
 1032:        no_set_ip_nexthop_cmd,
 1033:        "no set ip next-hop",
 1034:        NO_STR
 1035:        SET_STR
 1036:        IP_STR
 1037:        "Next hop address\n")
 1038: {
 1039:   if (argc == 0)
 1040:     return rip_route_set_delete (vty, vty->index, "ip next-hop", NULL);
 1041:   
 1042:   return rip_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
 1043: }
 1044: 
 1045: ALIAS (no_set_ip_nexthop,
 1046:        no_set_ip_nexthop_val_cmd,
 1047:        "no set ip next-hop A.B.C.D",
 1048:        NO_STR
 1049:        SET_STR
 1050:        IP_STR
 1051:        "Next hop address\n"
 1052:        "IP address of next hop\n")
 1053: 
 1054: DEFUN (set_tag,
 1055:        set_tag_cmd,
 1056:        "set tag <0-65535>",
 1057:        SET_STR
 1058:        "Tag value for routing protocol\n"
 1059:        "Tag value\n")
 1060: {
 1061:   return rip_route_set_add (vty, vty->index, "tag", argv[0]);
 1062: }
 1063: 
 1064: DEFUN (no_set_tag,
 1065:        no_set_tag_cmd,
 1066:        "no set tag",
 1067:        NO_STR
 1068:        SET_STR
 1069:        "Tag value for routing protocol\n")
 1070: {
 1071:   if (argc == 0)
 1072:     return rip_route_set_delete (vty, vty->index, "tag", NULL);
 1073:   
 1074:   return rip_route_set_delete (vty, vty->index, "tag", argv[0]);
 1075: }
 1076: 
 1077: ALIAS (no_set_tag,
 1078:        no_set_tag_val_cmd,
 1079:        "no set tag <0-65535>",
 1080:        NO_STR
 1081:        SET_STR
 1082:        "Tag value for routing protocol\n"
 1083:        "Tag value\n")
 1084: 
 1085: void
 1086: rip_route_map_reset ()
 1087: {
 1088:   ;
 1089: }
 1090: 
 1091: /* Route-map init */
 1092: void
 1093: rip_route_map_init ()
 1094: {
 1095:   route_map_init ();
 1096:   route_map_init_vty ();
 1097:   route_map_add_hook (rip_route_map_update);
 1098:   route_map_delete_hook (rip_route_map_update);
 1099: 
 1100:   route_map_install_match (&route_match_metric_cmd);
 1101:   route_map_install_match (&route_match_interface_cmd);
 1102:   route_map_install_match (&route_match_ip_next_hop_cmd);
 1103:   route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
 1104:   route_map_install_match (&route_match_ip_address_cmd);
 1105:   route_map_install_match (&route_match_ip_address_prefix_list_cmd);
 1106:   route_map_install_match (&route_match_tag_cmd);
 1107: 
 1108:   route_map_install_set (&route_set_metric_cmd);
 1109:   route_map_install_set (&route_set_ip_nexthop_cmd);
 1110:   route_map_install_set (&route_set_tag_cmd);
 1111: 
 1112:   install_element (RMAP_NODE, &match_metric_cmd);
 1113:   install_element (RMAP_NODE, &no_match_metric_cmd);
 1114:   install_element (RMAP_NODE, &no_match_metric_val_cmd);
 1115:   install_element (RMAP_NODE, &match_interface_cmd);
 1116:   install_element (RMAP_NODE, &no_match_interface_cmd);
 1117:   install_element (RMAP_NODE, &no_match_interface_val_cmd);
 1118:   install_element (RMAP_NODE, &match_ip_next_hop_cmd);
 1119:   install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
 1120:   install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
 1121:   install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
 1122:   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
 1123:   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
 1124:   install_element (RMAP_NODE, &match_ip_address_cmd);
 1125:   install_element (RMAP_NODE, &no_match_ip_address_cmd);
 1126:   install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
 1127:   install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
 1128:   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
 1129:   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
 1130:   install_element (RMAP_NODE, &match_tag_cmd);
 1131:   install_element (RMAP_NODE, &no_match_tag_cmd);
 1132:   install_element (RMAP_NODE, &no_match_tag_val_cmd);
 1133: 
 1134:   install_element (RMAP_NODE, &set_metric_cmd);
 1135:   install_element (RMAP_NODE, &set_metric_addsub_cmd);
 1136:   install_element (RMAP_NODE, &no_set_metric_cmd);
 1137:   install_element (RMAP_NODE, &no_set_metric_val_cmd);
 1138:   install_element (RMAP_NODE, &set_ip_nexthop_cmd);
 1139:   install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
 1140:   install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
 1141:   install_element (RMAP_NODE, &set_tag_cmd);
 1142:   install_element (RMAP_NODE, &no_set_tag_cmd);
 1143:   install_element (RMAP_NODE, &no_set_tag_val_cmd);
 1144: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>