File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / zebra_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, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

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