File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / zebra_routemap.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:11 2012 UTC (12 years, 4 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, v0_99_21, v0_99_20_1, v0_99_20, HEAD
quagga

    1: /* zebra routemap.
    2:  * Copyright (C) 2006 IBM Corporation
    3:  *
    4:  * This file is part of GNU Zebra.
    5:  *
    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
    9:  * later version.
   10:  *
   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.
   15:  *
   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
   19:  * 02111-1307, USA.  
   20:  */
   21: 
   22: #include <zebra.h>
   23: 
   24: #include "memory.h"
   25: #include "prefix.h"
   26: #include "rib.h"
   27: #include "routemap.h"
   28: #include "command.h"
   29: #include "filter.h"
   30: #include "plist.h"
   31: 
   32: #include "zebra/zserv.h"
   33: 
   34: /* Add zebra route map rule */
   35: static int
   36: zebra_route_match_add(struct vty *vty, struct route_map_index *index,
   37: 		      const char *command, const char *arg)
   38: {
   39:   int ret;
   40: 
   41:   ret = route_map_add_match (index, command, arg);
   42:   if (ret)
   43:     {
   44:       switch (ret)
   45: 	{
   46: 	case RMAP_RULE_MISSING:
   47: 	  vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
   48: 	  return CMD_WARNING;
   49: 	case RMAP_COMPILE_ERROR:
   50: 	  vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
   51: 	  return CMD_WARNING;
   52: 	}
   53:     }
   54:   return CMD_SUCCESS;
   55: }
   56: 
   57: /* Delete zebra route map rule. */
   58: static int
   59: zebra_route_match_delete (struct vty *vty, struct route_map_index *index,
   60: 			const char *command, const char *arg)
   61: {
   62:   int ret;
   63: 
   64:   ret = route_map_delete_match (index, command, arg);
   65:   if (ret)
   66:     {
   67:       switch (ret)
   68: 	{
   69: 	case RMAP_RULE_MISSING:
   70: 	  vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
   71: 	  return CMD_WARNING;
   72: 	case RMAP_COMPILE_ERROR:
   73: 	  vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
   74: 	  return CMD_WARNING;
   75: 	}
   76:     }
   77:   return CMD_SUCCESS;
   78: }
   79: 
   80: /* Add zebra route map rule. */
   81: static int
   82: zebra_route_set_add (struct vty *vty, struct route_map_index *index,
   83: 		   const char *command, const char *arg)
   84: {
   85:   int ret;
   86: 
   87:   ret = route_map_add_set (index, command, arg);
   88:   if (ret)
   89:     {
   90:       switch (ret)
   91: 	{
   92: 	case RMAP_RULE_MISSING:
   93: 	  vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
   94: 	  return CMD_WARNING;
   95: 	case RMAP_COMPILE_ERROR:
   96: 	  vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
   97: 	  return CMD_WARNING;
   98: 	}
   99:     }
  100:   return CMD_SUCCESS;
  101: }
  102: 
  103: /* Delete zebra route map rule. */
  104: static int
  105: zebra_route_set_delete (struct vty *vty, struct route_map_index *index,
  106: 		      const char *command, const char *arg)
  107: {
  108:   int ret;
  109: 
  110:   ret = route_map_delete_set (index, command, arg);
  111:   if (ret)
  112:     {
  113:       switch (ret)
  114: 	{
  115: 	case RMAP_RULE_MISSING:
  116: 	  vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  117: 	  return CMD_WARNING;
  118: 	case RMAP_COMPILE_ERROR:
  119: 	  vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  120: 	  return CMD_WARNING;
  121: 	}
  122:     }
  123:   return CMD_SUCCESS;
  124: }
  125: 
  126: 
  127: /* `match interface IFNAME' */
  128: /* Match function return 1 if match is success else return zero. */
  129: static route_map_result_t
  130: route_match_interface (void *rule, struct prefix *prefix,
  131: 		       route_map_object_t type, void *object)
  132: {
  133:   struct nexthop *nexthop;
  134:   char *ifname = rule;
  135:   unsigned int ifindex;
  136: 
  137:   if (type == RMAP_ZEBRA)
  138:     {
  139:       if (strcasecmp(ifname, "any") == 0)
  140: 	return RMAP_MATCH;
  141:       ifindex = ifname2ifindex(ifname);
  142:       if (ifindex == 0)
  143: 	return RMAP_NOMATCH;
  144:       nexthop = object;
  145:       if (!nexthop)
  146: 	return RMAP_NOMATCH;
  147:       if (nexthop->ifindex == ifindex)
  148: 	return RMAP_MATCH;
  149:     }
  150:   return RMAP_NOMATCH;
  151: }
  152: 
  153: /* Route map `match interface' match statement. `arg' is IFNAME value */
  154: static void *
  155: route_match_interface_compile (const char *arg)
  156: {
  157:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  158: }
  159: 
  160: /* Free route map's compiled `match interface' value. */
  161: static void
  162: route_match_interface_free (void *rule)
  163: {
  164:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  165: }
  166: 
  167: /* Route map commands for interface matching */
  168: struct route_map_rule_cmd route_match_interface_cmd =
  169: {
  170:    "interface",
  171:    route_match_interface,
  172:    route_match_interface_compile,
  173:    route_match_interface_free
  174: };
  175: 
  176: DEFUN (match_interface,
  177:        match_interface_cmd,
  178:        "match interface WORD",
  179:        MATCH_STR
  180:        "match first hop interface of route\n"
  181:        "Interface name\n")
  182: {
  183:   return zebra_route_match_add (vty, vty->index, "interface", argv[0]);
  184: }
  185: 
  186: DEFUN (no_match_interface,
  187:        no_match_interface_cmd,
  188:        "no match interface",
  189:        NO_STR
  190:        MATCH_STR
  191:        "Match first hop interface of route\n")
  192: {
  193:   if (argc == 0)
  194:     return zebra_route_match_delete (vty, vty->index, "interface", NULL);
  195: 
  196:   return zebra_route_match_delete (vty, vty->index, "interface", argv[0]);
  197: }
  198: 
  199: ALIAS (no_match_interface,
  200:        no_match_interface_val_cmd,
  201:        "no match interface WORD",
  202:        NO_STR
  203:        MATCH_STR
  204:        "Match first hop interface of route\n"
  205:        "Interface name\n")
  206: 
  207: DEFUN (match_ip_next_hop,
  208:        match_ip_next_hop_cmd,
  209:        "match ip next-hop (<1-199>|<1300-2699>|WORD)",
  210:        MATCH_STR
  211:        IP_STR
  212:        "Match next-hop address of route\n"
  213:        "IP access-list number\n"
  214:        "IP access-list number (expanded range)\n"
  215:        "IP Access-list name\n")
  216: {
  217:   return zebra_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
  218: }
  219: 
  220: DEFUN (no_match_ip_next_hop,
  221:        no_match_ip_next_hop_cmd,
  222:        "no match ip next-hop",
  223:        NO_STR
  224:        MATCH_STR
  225:        IP_STR
  226:        "Match next-hop address of route\n")
  227: {
  228:   if (argc == 0)
  229:     return zebra_route_match_delete (vty, vty->index, "ip next-hop", NULL);
  230: 
  231:   return zebra_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
  232: }
  233: 
  234: ALIAS (no_match_ip_next_hop,
  235:        no_match_ip_next_hop_val_cmd,
  236:        "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
  237:        NO_STR
  238:        MATCH_STR
  239:        IP_STR
  240:        "Match next-hop address of route\n"
  241:        "IP access-list number\n"
  242:        "IP access-list number (expanded range)\n"
  243:        "IP Access-list name\n")
  244: 
  245: DEFUN (match_ip_next_hop_prefix_list,
  246:        match_ip_next_hop_prefix_list_cmd,
  247:        "match ip next-hop prefix-list WORD",
  248:        MATCH_STR
  249:        IP_STR
  250:        "Match next-hop address of route\n"
  251:        "Match entries of prefix-lists\n"
  252:        "IP prefix-list name\n")
  253: {
  254:   return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  255: }
  256: 
  257: DEFUN (no_match_ip_next_hop_prefix_list,
  258:        no_match_ip_next_hop_prefix_list_cmd,
  259:        "no match ip next-hop prefix-list",
  260:        NO_STR
  261:        MATCH_STR
  262:        IP_STR
  263:        "Match next-hop address of route\n"
  264:        "Match entries of prefix-lists\n")
  265: {
  266:   if (argc == 0)
  267:     return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
  268: 
  269:   return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  270: }
  271: 
  272: ALIAS (no_match_ip_next_hop_prefix_list,
  273:        no_match_ip_next_hop_prefix_list_val_cmd,
  274:        "no match ip next-hop prefix-list WORD",
  275:        NO_STR
  276:        MATCH_STR
  277:        IP_STR
  278:        "Match next-hop address of route\n"
  279:        "Match entries of prefix-lists\n"
  280:        "IP prefix-list name\n")
  281: 
  282: DEFUN (match_ip_address,
  283:        match_ip_address_cmd,
  284:        "match ip address (<1-199>|<1300-2699>|WORD)",
  285:        MATCH_STR
  286:        IP_STR
  287:        "Match address of route\n"
  288:        "IP access-list number\n"
  289:        "IP access-list number (expanded range)\n"
  290:        "IP Access-list name\n")
  291: 
  292: {
  293:   return zebra_route_match_add (vty, vty->index, "ip address", argv[0]);
  294: }
  295: 
  296: DEFUN (no_match_ip_address, 
  297:        no_match_ip_address_cmd,
  298:        "no match ip address",
  299:        NO_STR
  300:        MATCH_STR
  301:        IP_STR
  302:        "Match address of route\n")
  303: {
  304:   if (argc == 0)
  305:     return zebra_route_match_delete (vty, vty->index, "ip address", NULL);
  306: 
  307:   return zebra_route_match_delete (vty, vty->index, "ip address", argv[0]);
  308: }
  309: 
  310: ALIAS (no_match_ip_address,
  311:        no_match_ip_address_val_cmd,
  312:        "no match ip address (<1-199>|<1300-2699>|WORD)",
  313:        NO_STR
  314:        MATCH_STR
  315:        IP_STR
  316:        "Match address of route\n"
  317:        "IP access-list number\n"
  318:        "IP access-list number (expanded range)\n"
  319:        "IP Access-list name\n")
  320: 
  321: DEFUN (match_ip_address_prefix_list, 
  322:        match_ip_address_prefix_list_cmd,
  323:        "match ip address prefix-list WORD",
  324:        MATCH_STR
  325:        IP_STR
  326:        "Match address of route\n"
  327:        "Match entries of prefix-lists\n"
  328:        "IP prefix-list name\n")
  329: {
  330:   return zebra_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
  331: }
  332: 
  333: DEFUN (no_match_ip_address_prefix_list,
  334:        no_match_ip_address_prefix_list_cmd,
  335:        "no match ip address prefix-list",
  336:        NO_STR
  337:        MATCH_STR
  338:        IP_STR
  339:        "Match address of route\n"
  340:        "Match entries of prefix-lists\n")
  341: {
  342:   if (argc == 0)
  343:     return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
  344: 
  345:   return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
  346: }
  347: 
  348: ALIAS (no_match_ip_address_prefix_list,
  349:        no_match_ip_address_prefix_list_val_cmd,
  350:        "no match ip address prefix-list WORD",
  351:        NO_STR
  352:        MATCH_STR
  353:        IP_STR
  354:        "Match address of route\n"
  355:        "Match entries of prefix-lists\n"
  356:        "IP prefix-list name\n")
  357: 
  358: /* set functions */
  359: 
  360: DEFUN (set_src,
  361:        set_src_cmd,
  362:        "set src A.B.C.D",
  363:        SET_STR
  364:        "src address for route\n"
  365:        "src address\n")
  366: {
  367:   struct in_addr src;
  368:   struct interface *pif;
  369: 
  370:   if (inet_pton(AF_INET, argv[0], &src) <= 0)
  371:     {
  372:       vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
  373:       return CMD_WARNING;
  374:     }
  375: 
  376:     pif = if_lookup_exact_address (src);
  377:     if (!pif)
  378:       {
  379:         vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
  380:         return CMD_WARNING;
  381:       }
  382:   return zebra_route_set_add (vty, vty->index, "src", argv[0]);
  383: }
  384: 
  385: DEFUN (no_set_src,
  386:        no_set_src_cmd,
  387:        "no set src",
  388:        NO_STR
  389:        SET_STR
  390:        "Source address for route\n")
  391: {
  392:   if (argc == 0)
  393:     return zebra_route_set_delete (vty, vty->index, "src", NULL);
  394: 
  395:   return zebra_route_set_delete (vty, vty->index, "src", argv[0]);
  396: }
  397: 
  398: ALIAS (no_set_src,
  399:        no_set_src_val_cmd,
  400:        "no set src (A.B.C.D)",
  401:        NO_STR
  402:        SET_STR
  403:        "src address for route\n"
  404:        "src address\n")
  405: 
  406: /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
  407: 
  408: /* `match ip next-hop IP_ACCESS_LIST' */
  409: 
  410: /* Match function return 1 if match is success else return zero. */
  411: static route_map_result_t
  412: route_match_ip_next_hop (void *rule, struct prefix *prefix,
  413: 			route_map_object_t type, void *object)
  414: {
  415:   struct access_list *alist;
  416:   struct nexthop *nexthop;
  417:   struct prefix_ipv4 p;
  418: 
  419:   if (type == RMAP_ZEBRA)
  420:     {
  421:       nexthop = object;
  422:       switch (nexthop->type) {
  423:       case NEXTHOP_TYPE_IFINDEX:
  424:       case NEXTHOP_TYPE_IFNAME:
  425:       case NEXTHOP_TYPE_IPV4_IFINDEX:
  426:       case NEXTHOP_TYPE_IPV4_IFNAME:
  427:         if (nexthop->rtype != NEXTHOP_TYPE_IPV4)
  428: 		return RMAP_NOMATCH;
  429:         p.family = AF_INET;
  430:         p.prefix = nexthop->rgate.ipv4;
  431:         p.prefixlen = IPV4_MAX_BITLEN;
  432:         break;
  433:       case NEXTHOP_TYPE_IPV4:
  434:         p.family = AF_INET;
  435:         p.prefix = nexthop->gate.ipv4;
  436:         p.prefixlen = IPV4_MAX_BITLEN;
  437:         break;
  438:       default:
  439:         return RMAP_NOMATCH;
  440:       }
  441:       alist = access_list_lookup (AFI_IP, (char *) rule);
  442:       if (alist == NULL)
  443: 	return RMAP_NOMATCH;
  444: 
  445:       return (access_list_apply (alist, &p) == FILTER_DENY ?
  446: 	      RMAP_NOMATCH : RMAP_MATCH);
  447:     }
  448:   return RMAP_NOMATCH;
  449: }
  450: 
  451: /* Route map `ip next-hop' match statement.  `arg' should be
  452:    access-list name. */
  453: static void *
  454: route_match_ip_next_hop_compile (const char *arg)
  455: {
  456:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  457: }
  458: 
  459: /* Free route map's compiled `. */
  460: static void
  461: route_match_ip_next_hop_free (void *rule)
  462: {
  463:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  464: }
  465: 
  466: /* Route map commands for ip next-hop matching. */
  467: static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
  468: {
  469:   "ip next-hop",
  470:   route_match_ip_next_hop,
  471:   route_match_ip_next_hop_compile,
  472:   route_match_ip_next_hop_free
  473: };
  474: 
  475: /* `match ip next-hop prefix-list PREFIX_LIST' */
  476: 
  477: static route_map_result_t
  478: route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
  479:                                     route_map_object_t type, void *object)
  480: {
  481:   struct prefix_list *plist;
  482:   struct nexthop *nexthop;
  483:   struct prefix_ipv4 p;
  484: 
  485:   if (type == RMAP_ZEBRA)
  486:     {
  487:       nexthop = object;
  488:       switch (nexthop->type) {
  489:       case NEXTHOP_TYPE_IFINDEX:
  490:       case NEXTHOP_TYPE_IFNAME:
  491:       case NEXTHOP_TYPE_IPV4_IFINDEX:
  492:       case NEXTHOP_TYPE_IPV4_IFNAME:
  493:         if (nexthop->rtype != NEXTHOP_TYPE_IPV4)
  494: 		return RMAP_NOMATCH;
  495:         p.family = AF_INET;
  496:         p.prefix = nexthop->rgate.ipv4;
  497:         p.prefixlen = IPV4_MAX_BITLEN;
  498:         break;
  499:       case NEXTHOP_TYPE_IPV4:
  500:         p.family = AF_INET;
  501:         p.prefix = nexthop->gate.ipv4;
  502:         p.prefixlen = IPV4_MAX_BITLEN;
  503:         break;
  504:       default:
  505:         return RMAP_NOMATCH;
  506:       }
  507:       plist = prefix_list_lookup (AFI_IP, (char *) rule);
  508:       if (plist == NULL)
  509:         return RMAP_NOMATCH;
  510: 
  511:       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
  512:               RMAP_NOMATCH : RMAP_MATCH);
  513:     }
  514:   return RMAP_NOMATCH;
  515: }
  516: 
  517: static void *
  518: route_match_ip_next_hop_prefix_list_compile (const char *arg)
  519: {
  520:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  521: }
  522: 
  523: static void
  524: route_match_ip_next_hop_prefix_list_free (void *rule)
  525: {
  526:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  527: }
  528: 
  529: static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
  530: {
  531:   "ip next-hop prefix-list",
  532:   route_match_ip_next_hop_prefix_list,
  533:   route_match_ip_next_hop_prefix_list_compile,
  534:   route_match_ip_next_hop_prefix_list_free
  535: };
  536: 
  537: /* `match ip address IP_ACCESS_LIST' */
  538: 
  539: /* Match function should return 1 if match is success else return
  540:    zero. */
  541: static route_map_result_t
  542: route_match_ip_address (void *rule, struct prefix *prefix, 
  543: 			route_map_object_t type, void *object)
  544: {
  545:   struct access_list *alist;
  546: 
  547:   if (type == RMAP_ZEBRA)
  548:     {
  549:       alist = access_list_lookup (AFI_IP, (char *) rule);
  550:       if (alist == NULL)
  551: 	return RMAP_NOMATCH;
  552:     
  553:       return (access_list_apply (alist, prefix) == FILTER_DENY ?
  554: 	      RMAP_NOMATCH : RMAP_MATCH);
  555:     }
  556:   return RMAP_NOMATCH;
  557: }
  558: 
  559: /* Route map `ip address' match statement.  `arg' should be
  560:    access-list name. */
  561: static void *
  562: route_match_ip_address_compile (const char *arg)
  563: {
  564:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  565: }
  566: 
  567: /* Free route map's compiled `ip address' value. */
  568: static void
  569: route_match_ip_address_free (void *rule)
  570: {
  571:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  572: }
  573: 
  574: /* Route map commands for ip address matching. */
  575: static struct route_map_rule_cmd route_match_ip_address_cmd =
  576: {
  577:   "ip address",
  578:   route_match_ip_address,
  579:   route_match_ip_address_compile,
  580:   route_match_ip_address_free
  581: };
  582: 
  583: /* `match ip address prefix-list PREFIX_LIST' */
  584: 
  585: static route_map_result_t
  586: route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, 
  587: 				    route_map_object_t type, void *object)
  588: {
  589:   struct prefix_list *plist;
  590: 
  591:   if (type == RMAP_ZEBRA)
  592:     {
  593:       plist = prefix_list_lookup (AFI_IP, (char *) rule);
  594:       if (plist == NULL)
  595: 	return RMAP_NOMATCH;
  596:     
  597:       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  598: 	      RMAP_NOMATCH : RMAP_MATCH);
  599:     }
  600:   return RMAP_NOMATCH;
  601: }
  602: 
  603: static void *
  604: route_match_ip_address_prefix_list_compile (const char *arg)
  605: {
  606:   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  607: }
  608: 
  609: static void
  610: route_match_ip_address_prefix_list_free (void *rule)
  611: {
  612:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  613: }
  614: 
  615: static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
  616: {
  617:   "ip address prefix-list",
  618:   route_match_ip_address_prefix_list,
  619:   route_match_ip_address_prefix_list_compile,
  620:   route_match_ip_address_prefix_list_free
  621: };
  622: 
  623: 
  624: /* `set src A.B.C.D' */
  625: 
  626: /* Set src. */
  627: static route_map_result_t
  628: route_set_src (void *rule, struct prefix *prefix, 
  629: 		  route_map_object_t type, void *object)
  630: {
  631:   if (type == RMAP_ZEBRA)
  632:     {
  633:       struct nexthop *nexthop;
  634: 
  635:       nexthop = object;
  636:       nexthop->src = *(union g_addr *)rule;
  637:     }
  638:   return RMAP_OKAY;
  639: }
  640: 
  641: /* set src compilation. */
  642: static void *
  643: route_set_src_compile (const char *arg)
  644: {
  645:   union g_addr src, *psrc;
  646: 
  647:   if (inet_pton(AF_INET, arg, &src.ipv4) != 1
  648: #ifdef HAVE_IPV6
  649:       && inet_pton(AF_INET6, arg, &src.ipv6) != 1
  650: #endif /* HAVE_IPV6 */
  651:      )
  652:     return NULL;
  653: 
  654:   psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
  655:   *psrc = src;
  656: 
  657:   return psrc;
  658: }
  659: 
  660: /* Free route map's compiled `set src' value. */
  661: static void
  662: route_set_src_free (void *rule)
  663: {
  664:   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  665: }
  666: 
  667: /* Set src rule structure. */
  668: static struct route_map_rule_cmd route_set_src_cmd = 
  669: {
  670:   "src",
  671:   route_set_src,
  672:   route_set_src_compile,
  673:   route_set_src_free,
  674: };
  675: 
  676: void
  677: zebra_route_map_init ()
  678: {
  679:   route_map_init ();
  680:   route_map_init_vty ();
  681: 
  682:   route_map_install_match (&route_match_interface_cmd);
  683:   route_map_install_match (&route_match_ip_next_hop_cmd);
  684:   route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
  685:   route_map_install_match (&route_match_ip_address_cmd);
  686:   route_map_install_match (&route_match_ip_address_prefix_list_cmd);
  687: /* */
  688:   route_map_install_set (&route_set_src_cmd);
  689: /* */
  690:   install_element (RMAP_NODE, &match_interface_cmd);
  691:   install_element (RMAP_NODE, &no_match_interface_cmd); 
  692:   install_element (RMAP_NODE, &no_match_interface_val_cmd); 
  693:   install_element (RMAP_NODE, &match_ip_next_hop_cmd); 
  694:   install_element (RMAP_NODE, &no_match_ip_next_hop_cmd); 
  695:   install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd); 
  696:   install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd); 
  697:   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd); 
  698:   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd); 
  699:   install_element (RMAP_NODE, &match_ip_address_cmd); 
  700:   install_element (RMAP_NODE, &no_match_ip_address_cmd); 
  701:   install_element (RMAP_NODE, &no_match_ip_address_val_cmd); 
  702:   install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd); 
  703:   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd); 
  704:   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
  705: /* */
  706:   install_element (RMAP_NODE, &set_src_cmd);
  707:   install_element (RMAP_NODE, &no_set_src_cmd);
  708: }

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