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