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 36struct 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. */ 49static int 50rip_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. */ 72static int 73rip_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. */ 95static int 96rip_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. */ 124static int 125rip_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 */ 148static void 149rip_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. */ 166static route_map_result_t 167route_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 */ 192static void * 193route_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. */ 208static void 209route_match_metric_free (void *rule) 210{ 211 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 212} 213 214/* Route map commands for metric matching. */ 215struct 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. */ 225static route_map_result_t 226route_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? */ 253static void * 254route_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. */ 260static void 261route_match_interface_free (void *rule) 262{ 263 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 264} 265 266/* Route map commands for interface matching. */ 267struct 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. */ 278static route_map_result_t 279route_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. */ 305static void * 306route_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 `. */ 312static void 313route_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. */ 319static 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 329static route_map_result_t 330route_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 354static void * 355route_match_ip_next_hop_prefix_list_compile (const char *arg) 356{ 357 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); 358} 359 360static void 361route_match_ip_next_hop_prefix_list_free (void *rule) 362{ 363 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 364} 365 366static 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. */ 378static route_map_result_t 379route_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. */ 398static void * 399route_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. */ 405static void 406route_match_ip_address_free (void *rule) 407{ 408 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 409} 410 411/* Route map commands for ip address matching. */ 412static 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 422static route_map_result_t 423route_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 440static void * 441route_match_ip_address_prefix_list_compile (const char *arg) 442{ 443 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); 444} 445 446static void 447route_match_ip_address_prefix_list_free (void *rule) 448{ 449 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 450} 451 452static 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. */ 462static route_map_result_t 463route_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 */ 484static void * 485route_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. */ 496static void 497route_match_tag_free (void *rule) 498{ 499 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 500} 501 502/* Route map commands for tag matching. */ 503struct 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. */ 514static route_map_result_t 515route_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. */ 544static void * 545route_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. */ 595static void 596route_set_metric_free (void *rule) 597{ 598 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 599} 600 601/* Set metric rule structure. */ 602static 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. */ 613static route_map_result_t 614route_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. */ 635static void * 636route_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. */ 655static void 656route_set_ip_nexthop_free (void *rule) 657{ 658 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 659} 660 661/* Route map commands for ip nexthop set. */ 662static 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. */ 673static route_map_result_t 674route_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. */ 695static void * 696route_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. */ 707static void 708route_set_tag_free (void *rule) 709{ 710 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 711} 712 713/* Route map commands for tag set. */ 714static 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 725DEFUN (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 735DEFUN (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 748ALIAS (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 756DEFUN (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 766DEFUN (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 779ALIAS (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 787DEFUN (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 800DEFUN (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 814ALIAS (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 825DEFUN (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 837DEFUN (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 852ALIAS (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 862DEFUN (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 876DEFUN (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 890ALIAS (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 901DEFUN (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 913DEFUN (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 928ALIAS (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 938DEFUN (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 948DEFUN (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 961ALIAS (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 971DEFUN (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 981ALIAS (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 988DEFUN (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 1001ALIAS (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 1010DEFUN (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 1031DEFUN (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 1045ALIAS (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 1054DEFUN (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 1064DEFUN (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 1077ALIAS (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 1085void 1086rip_route_map_reset () 1087{ 1088 ; 1089} 1090 1091/* Route-map init */ 1092void 1093rip_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} 1145