Annotation of embedaddon/quagga/ripd/rip_routemap.c, revision 1.1.1.2

1.1       misho       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"
1.1.1.2 ! misho      35: 
1.1       misho      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: }
1.1.1.2 ! misho     163: 
1.1       misho     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: };
1.1.1.2 ! misho     326: 
1.1       misho     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: };
1.1.1.2 ! misho     373: 
1.1       misho     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: };
1.1.1.2 ! misho     419: 
1.1       misho     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: };
1.1.1.2 ! misho     510: 
1.1       misho     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: };
1.1.1.2 ! misho     721: 
1.1       misho     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>